【问题标题】:Java: Deserialize a json to object in rest template using "@class" in json -SpringBootJava:使用json-SpringBoot中的“​​@class”将json反序列化为rest模板中的对象
【发布时间】:2015-08-12 04:56:12
【问题描述】:

我必须使用@class 中的信息实例化一个从 JSON 扩展抽象类的类,如下所示。

"name": {
  "health": "xxx",
  "animal": {
    "_class": "com.example.Dog",
    "height" : "20"
    "color" : "white"
  }
},

这里的抽象类是animal,而dog扩展了animal类。那么使用@class中的信息,我们可以直接实例化dog。这也是我在 restTemplate 中得到的响应

ResponseEntity<List<SomeListName>> response = restTemplate.exchange("http://10.150.15.172:8080/agencies", HttpMethod.GET, request, responseType);

执行此行时出现以下错误。 由于 POJO 类是自动生成的,我不能使用像 @JsonTypeInfo

这样的注释

我正在使用 Spring Boot 和 Maven。 控制台出现此错误。

无法读取 JSON:无法构造“MyPOJO”的实例,问题:抽象类型要么需要映射到具体类型,要么具有自定义反序列化器,要么使用额外的类型信息进行实例化

【问题讨论】:

    标签: java jackson spring-boot deserialization resttemplate


    【解决方案1】:

    你可以使用@JsonTypeInfo注解,不管类是不是生成的,遵守MixIn's

    “mix-in annotations are”:一种将注释与 类,而不修改(目标)类本身。

    也就是说,您可以:

    定义将使用混合类(或接口)的注释 使用目标类(或接口),使其看起来好像 目标类具有混合类具有的所有注释(对于 配置序列化/反序列化的目的)

    所以你可以写你的 AnimalMixIn 类,比如

    @JsonTypeInfo(  
        use = JsonTypeInfo.Id.NAME,  
        include = JsonTypeInfo.As.PROPERTY,  
        property = "_class")  
    @JsonSubTypes({  
        @Type(value = Cat.class, name = "com.example.Cat"),  
        @Type(value = Dog.class, name = "com.example.Dog") })  
    abstract class AnimalMixIn  
    {  
    
    }  
    

    并配置您的反序列化器

        ObjectMapper mapper = new ObjectMapper();  
        mapper.getDeserializationConfig().addMixInAnnotations(  
        Animal.class, AnimalMixIn.class);
    

    由于您使用的是 Spring Boot,您可以查看以下博客文章,了解如何自定义 ObjectMapper 以使用 MixIn,Customizing the Jackson Object Mapper,特别注意 Jackson2ObjectMapperBuildermixIn 方法

    RestTemplate 中使用自定义ObjectMapper 应通过转换器设置,例如

        RestTemplate restTemplate = new RestTemplate();
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
        MappingJackson2HttpMessageConverter jsonMessageConverter = new MappingJackson2HttpMessageConverter();
        jsonMessageConverter.setObjectMapper(objectMapper);
        messageConverters.add(jsonMessageConverter);
        restTemplate.setMessageConverters(messageConverters);
        return restTemplate;
    

    【讨论】:

    • 非常感谢您的回答。但是由于我使用的是 Spring Boot,我是否必须使用任何自定义对象映射器来替换 HttpMessageConverter 在restTemplate 中的默认对象映射器。
    • 欢迎您,是的,您必须自定义默认对象映射器,我在答案中提供了一些参考
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    相关资源
    最近更新 更多