Java:使用json-SpringBoot中的“​​@class”将json反序列化为rest模板中的对象

Posted

技术标签:

【中文标题】Java:使用json-SpringBoot中的“​​@class”将json反序列化为rest模板中的对象【英文标题】:Java: Deserialize a json to object in rest template using "@class" in json -SpringBoot 【发布时间】: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”的实例,问题:抽象类型要么需要映射到具体类型,要么具有自定义反序列化器,要么使用额外的类型信息进行实例化

【问题讨论】:

【参考方案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,特别注意 Jackson2ObjectMapperBuilder 的 mixIn 方法

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 中的默认对象映射器。 欢迎您,是的,您必须自定义默认对象映射器,我在答案中提供了一些参考

以上是关于Java:使用json-SpringBoot中的“​​@class”将json反序列化为rest模板中的对象的主要内容,如果未能解决你的问题,请参考以下文章

java中的多态 到底怎么使用

JAVA中的JPanel怎么使用呢?

怎么使用java中的枚举方法

java 使用Java中的Scanner输入

NoClassDefFoundError 使用 Java 中的 Scala 类

将命名空间从 java 传递给 xslt,并使用 java 中的参数作为 xslt 中的节点