Java 当我尝试反序列化Abstract类时,Jackson Objectmapper在配置为bean之后并没有被Spring初始化

Java 当我尝试反序列化Abstract类时,Jackson Objectmapper在配置为bean之后并没有被Spring初始化,java,spring-boot,jackson,jackson-databind,Java,Spring Boot,Jackson,Jackson Databind,我在spring boot应用程序中使用Jackson xml 2.9.9版 我有一个接受Vehicle的控制器,Vehicle是一个抽象类,有两个子类。 当我从邮递员传递JSON数据时,我无法反序列化车辆,因为自动连接的对象映射器始终为空(我将objectmapper配置为bean,因为我将反序列化器设置为映射器的简单模块)。请查看中的示例代码 控制器 MyModel.java Vehicle.java java Auto.java ObjectMapperbean配置 问题: 对象映射器未被

我在spring boot应用程序中使用Jackson xml 2.9.9版

我有一个接受Vehicle的控制器,Vehicle是一个抽象类,有两个子类。 当我从邮递员传递JSON数据时,我无法反序列化车辆,因为自动连接的对象映射器始终为空(我将objectmapper配置为bean,因为我将反序列化器设置为映射器的简单模块)。请查看中的示例代码

控制器

MyModel.java

Vehicle.java

java

Auto.java

ObjectMapperbean配置

问题: 对象映射器未被注入且为空

我刚刚发现,在VehicleDeserializer.java中没有初始化对象映射器,我也没有找到在没有ObjectMapper帮助的情况下将字符串反序列化为Car/Auto的方法

我试了各种方法,但似乎都不管用

我将此作为一个单独的问题添加,因为我需要修复注入Objectmapper,或者在不使用Objectmapper的情况下反序列化Car/Auto(我仍然只能使用Fasterxml)

在VehicleDeserializer.java中创建新的ObjectMapper没有帮助,因为它总是为Car/Auto返回null对象,即使我向其添加了反序列化程序。 我举了这个例子,因为它只是一个例子。
我需要jackson完成反序列化

无需尝试在自定义反序列化程序中插入
ObjectMapper
。您可以使用:

ObjectMapper映射器=(ObjectMapper)jsonParser.getCodec();
如果不需要来自
ObjectMapper
的任何方法,则不需要强制转换:

ObjectCodec codec=jsonParser.getCodec();

无需尝试在自定义反序列化程序中插入
ObjectMapper
。您可以使用:

ObjectMapper映射器=(ObjectMapper)jsonParser.getCodec();
如果不需要来自
ObjectMapper
的任何方法,则不需要强制转换:

ObjectCodec codec=jsonParser.getCodec();

问题的原因是,您正在这样做:

modules.add(new SimpleModule().addDeserializer(Vehicle.class, new VehicleDeserializer()));

您自己正在实例化对象,因此映射器将为空。

问题的原因是,您正在执行以下操作:

modules.add(new SimpleModule().addDeserializer(Vehicle.class, new VehicleDeserializer()));

您自己正在实例化对象,因此映射器将为空。

您在反序列化程序中犯了一些错误:

  • 因为您已将反序列化程序注册到反序列化程序中的
    ObjectMapper
    对象,所以可以通过
    (ObjectMapper)parser.getCodec()
    获取它,其中
    parser
    JsonParser
    类型
  • findPath
    方法返回
    JsonNode
    not
    String
    so
    .equals(“”)
    始终返回
    false
    。您应该改用
    isMissingNode
    方法
  • 当您在
    解析器
    对象上使用
    readTree
    方法时,您不能再次使用它,因为反序列化已经完成,并且您有一个
    JsonNode
    。从现在起,你应该使用它。您可以使用
    convertValue
    方法将其转换为所需的
应该是这样的:

class VehicleDeserializer extends JsonDeserializer<Vehicle> {

    @Override
    public Vehicle deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {
        // cast to ObjectMapper
        ObjectMapper mapper = (ObjectMapper) parser.getCodec();

        // read JSON as tree to JsonNode object
        // since now `parser` should not be used anymore.
        JsonNode root = mapper.readTree(parser);
        Vehicle vehicle = null;
        if (!root.findPath("carDriverName").isMissingNode()) {
            vehicle = mapper.convertValue(root, Car.class);
        } else if (!root.findPath("autoDriverName").isMissingNode()) {
            vehicle = mapper.convertValue(root, Auto.class);
        }
        return vehicle;
    }
}
class VehicleDeserializer扩展JsonDeserializer{
@凌驾
公共车辆反序列化(JsonParser解析器、反序列化上下文反序列化上下文)引发IOException{
//强制转换到ObjectMapper
ObjectMapper映射器=(ObjectMapper)parser.getCodec();
//将JSON作为树读取到JsonNode对象
//现在不应该再使用“parser”。
JsonNode root=mapper.readTree(解析器);
车辆=空;
如果(!root.findPath(“carDriverName”).isMissingNode()){
vehicle=mapper.convertValue(根,Car.class);
}如果(!root.findPath(“autoDriverName”).isMissingNode(),则为else{
vehicle=mapper.convertValue(根,自动类);
}
返回车辆;
}
}

您在反序列化程序中犯了一些错误:

  • 因为您已将反序列化程序注册到反序列化程序中的
    ObjectMapper
    对象,所以可以通过
    (ObjectMapper)parser.getCodec()
    获取它,其中
    parser
    JsonParser
    类型
  • findPath
    方法返回
    JsonNode
    not
    String
    so
    .equals(“”)
    始终返回
    false
    。您应该改用
    isMissingNode
    方法
  • 当您在
    解析器
    对象上使用
    readTree
    方法时,您不能再次使用它,因为反序列化已经完成,并且您有一个
    JsonNode
    。从现在起,你应该使用它。您可以使用
    convertValue
    方法将其转换为所需的
应该是这样的:

class VehicleDeserializer extends JsonDeserializer<Vehicle> {

    @Override
    public Vehicle deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {
        // cast to ObjectMapper
        ObjectMapper mapper = (ObjectMapper) parser.getCodec();

        // read JSON as tree to JsonNode object
        // since now `parser` should not be used anymore.
        JsonNode root = mapper.readTree(parser);
        Vehicle vehicle = null;
        if (!root.findPath("carDriverName").isMissingNode()) {
            vehicle = mapper.convertValue(root, Car.class);
        } else if (!root.findPath("autoDriverName").isMissingNode()) {
            vehicle = mapper.convertValue(root, Auto.class);
        }
        return vehicle;
    }
}
class VehicleDeserializer扩展JsonDeserializer{
@凌驾
公共车辆反序列化(JsonParser解析器、反序列化上下文反序列化上下文)引发IOException{
//强制转换到ObjectMapper
ObjectMapper映射器=(ObjectMapper)parser.getCodec();
//将JSON作为树读取到JsonNode对象
//现在不应该再使用“parser”。
JsonNode root=mapper.readTree(解析器);
车辆=空;
如果(!root.findPath(“carDriverName”).isMissingNode()){
vehicle=mapper.convertValue(根,Car.class);
}如果(!root.findPath(“autoDriverName”).isMissingNode(),则为else{
vehicle=mapper.convertValue(根,自动类);
}
返回车辆;
}
}

如果没有一个最小的可复制示例,恐怕很难在这方面为您提供帮助。请发表一篇文章,重复这个问题。使用尽可能少的字段/小的代码,但确保您发布的内容在没有其他内容的情况下编译和运行。你甚至可以自己找到问题的原因,因为你说它可以反序列化
Lis
public class Auto extends Vehicle {
    private String autoType;
    private String autoDriverName;
}
@Configuration
public class MapperConfig {
    @Bean
    public ObjectMapper objectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();//Jackson2ObjectMapperBuilder.json().build();
        List<Module> modules = new ArrayList<>();
        modules.add(new SimpleModule().addDeserializer(Vehicle.class, new VehicleDeserializer()));
        objectMapper.registerModules(modules);
        return objectMapper;
    }
}
public class VehicleDeserializer extends JsonDeserializer<Vehicle> {

    @Autowired
    private ObjectMapper objectMapper;
    @Override
    public Vehicle deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);
        Vehicle vehicle=null;
        if (!jsonNode.findPath("carDriverName").equals("")){
            vehicle = objectMapper.readValue(jsonParser, Car.class);
        }else if (!jsonNode.findPath("autoDriverName").equals("")){
            vehicle = objectMapper.readValue(jsonParser, Auto.class);
        }
        return vehicle;
    }
}
{
    "name": "Bajaj",
    "value": {
        "autoDriverName": "Mr Auto Driver",
        "autoType": "commercial"
    }
}
modules.add(new SimpleModule().addDeserializer(Vehicle.class, new VehicleDeserializer()));
class VehicleDeserializer extends JsonDeserializer<Vehicle> {

    @Override
    public Vehicle deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {
        // cast to ObjectMapper
        ObjectMapper mapper = (ObjectMapper) parser.getCodec();

        // read JSON as tree to JsonNode object
        // since now `parser` should not be used anymore.
        JsonNode root = mapper.readTree(parser);
        Vehicle vehicle = null;
        if (!root.findPath("carDriverName").isMissingNode()) {
            vehicle = mapper.convertValue(root, Car.class);
        } else if (!root.findPath("autoDriverName").isMissingNode()) {
            vehicle = mapper.convertValue(root, Auto.class);
        }
        return vehicle;
    }
}