当前位置: 首页 > 知识库问答 >
问题:

当我尝试反序列化abstarct类时,jackson Objectmapper被配置为bean后,没有被spring初始化

柴嘉年
2023-03-14

我正在spring boot应用程序中使用jackson xml版本2.9.9。

我有一个控制器,接受车辆,这是一个抽象的类,有两个孩子类。当我从postman传递JSON数据时,我无法反序列化Vehicle,因为object mapper(自动连接的)总是空(我将objectmapper配置为bean,因为我将反序列化器设置为mapper的简单模块)。请查看https://github.com/vin0010/jackson-mapper-issue中的示例代码

控制器

@RequestMapping(path = "/jackson", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public void forSingleObject(@RequestBody MyModel myModel){
        System.out.println("Deserialization successful");
    }

myModel.java

public class MyModel {
    private String name;
    private Vehicle value;
}

vehicle.java

public abstract class Vehicle {
    private String vehicleName;
}

car.java

public class Car extends Vehicle{
    private String carType;
    private String carDriverName;
}

auto.java

public class Auto extends Vehicle {
    private String autoType;
    private String autoDriverName;
}

ObjectMapper bean配置

@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;
    }
}

VehicleDeserializer.java

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;
    }
}

JSON输入

{
    "name": "Bajaj",
    "value": {
        "autoDriverName": "Mr Auto Driver",
        "autoType": "commercial"
    }
}

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

我刚刚发现,在VehicleDeserializer.java中既没有初始化对象映射器,也没有找到不借助ObjectMapper将string反序列化为CAR/AUTO的方法。

我尝试了如何获得spring 4.1使用的jackson ObjectMapper的所有方法?但似乎什么都不起作用。

我将此作为一个单独的问题添加进来,因为我要么需要修复注入Objectmapper,要么不使用Objectmapper反序列化CAR/AUTO(仍然只能使用Fasterxml)。

在VehicleDeserializer.java中创建一个新的ObjectMapper并没有帮助,因为它总是为CAR/AUTO返回null对象,即使我向它添加了反序列化器。我之所以做这个例子,是因为它只是一个https://stackoverflow.com/help/minimal-reproducible-example。我需要jackson完成解序列化

共有2个答案

薛俊美
2023-03-14

你的问题的原因,你是这样做的:

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

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

程志新
2023-03-14

不需要尝试在自定义反序列化程序中注入objectmapper。您可以使用:

ObjectMapper mapper = (ObjectMapper) jsonParser.getCodec();

如果不需要objectmapper中的任何方法,则不需要强制转换:

ObjectCodec codec = jsonParser.getCodec();
 类似资料:
  • 问题内容: 我对Swift类有疑问。我有一个UITableViewController类和UITableViewCell类的快捷文件。我的问题是UITableViewCell类和插座。此类存在错误 类别“ HomeCell”没有初始化程序 ,并且我不理解此问题。 感谢您的回复。 问题答案: 您必须使用隐式展开的可选变量,以便Swift可以在初始化阶段处理循环依赖关系(在这种情况下,UI组件的父级<

  • 问题内容: 我有多个上下文文件。要求是:在其余的Bean中首先初始化一个特定的Bean(进行一些配置更改)。 有没有一种方法可以首先加载该bean? 一种选择是使用“取决于”属性。 但这将需要更新所有其他bean,因此这似乎不是最佳解决方案。 我们有更好的选择吗? 问题答案: 恕我直言,您应该等待它们修复https://jira.spring.io/browse/SPR-3948 一种可能的方法是

  • 我无法找到在tomcat停止的情况下,当我的应用程序关闭时,没有被调用的原因。 我有一个web应用程序,通过web.xml中的ContextLoaderListener加载spring上下文,如下所示: web.xml 下面是我的应用程序中的员工bean: Employee.class bean在我的应用程序上下文文件中定义如下: appContext.xml Tomcat控制台日志: 当我启动我

  • 我正在使用spring-security saml扩展为我的应用程序实现IDP启动的SSO。我正在使用https协议,签名/加密处于打开状态。我不需要SLO/SP启动的SSO。 要解密SAMLAuthResponse消息,是否需要SP的证书私钥? 如果我需要私钥,当我有jks文件jks-pwd别名,但没有privateKey的pwd时,如何为keyManager创建bean定义?是否可以在别名-密

  • 使用gcc 7.4.0并使用-O1优化标志编译此示例程序,数组“cap”中设置的数据正在优化,留下未初始化的数据。 编译代码: 输出如下: Valgrind在运行优化的二进制文件时报告以下内容: 如果我使用gcc-fno-tree dce-fno-tree dse标志和-O1,我会得到正确的输出。我想了解GCC正在做什么,它是一个GCC错误,还是有一种不同的方式来编写上述代码,而不会触发这个问题?

  • 我写了两个函数,用于在树中添加一个新节点:一个公共的和一个私有的。私有的是递归的。公共的调用递归的。第一个问题:这是可以接受的做法吗? 现在问题来了:根变量没有初始化。它在树类中声明<代码>公共节点根 这让我非常困惑,因为我知道Java是按引用传递的,而不是按值传递的。为什么在调用这些函数后root为null? 控制台输出: