使用@JsonSubTypes反序列化没有值 – 缺少属性错误

我像这样反序列化jsons:

{ "type":"a", "payload" : {...} } 

有效负载类型取决于类型。 我的课:

 public class Sth { @JsonProperty("type") private String type; @Valid private T payload; @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type", visible = true, defaultImpl = NoClass.class) @JsonSubTypes({ @JsonSubTypes.Type(value = APayload.class, name = "a"), @JsonSubTypes.Type(value = BPayload.class, name = "b"), @JsonSubTypes.Type(value = CPayload.class, name = "c")}) public void setPayload(T payload) { this.payload = payload; } public void setType(String type) { this.type = type; } } 

我也输入了没有有效载荷的“d”。 如果我尝试反序列化:

 { "type":"d", "payload" : null } 

它可以工作,但它没有负载有效:

 { "type":"d", } 

如何让它与上一个例子一起工作?

我得到错误的Stacktrace:

 [error] Caused by: com.fasterxml.jackson.databind.JsonMappingException: Missing property 'payload' for external type id 'type [error] at [Source: N/A; line: -1, column: -1] [error] at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164) [error] at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:700) [error] at com.fasterxml.jackson.databind.deser.impl.ExternalTypeHandler.complete(ExternalTypeHandler.java:160) [error] at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithExternalTypeId(BeanDeserializer.java:690) [error] at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithExternalTypeId(BeanDeserializer.java:639) [error] at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:266) [error] at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124) [error] at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:2965) [error] at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1587) [error] at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:1931) [error] at play.libs.Json.fromJson(Json.java:47) 

我也遇到过这个问题,并且使用Jackson提供的机制(自定义BeanDeserializerBeanDeserializerModifier等)找不到优雅的解决方案。

它看起来像处理外部类型ID的方式中的错误。 我解决了以下问题:

  1. 将JSON tring反序列化为JsonNode ;
  2. 如果不存在required属性,则手动插入null节点;
  3. JsonNode映射到我想要的值类型。

我的代码如下所示:

 public  T decode(String json, Class type) throws IOException { JsonNode jsonNode = mapper.readTree(json); if (jsonNode.isObject() && (jsonNode.get("payload") == null || jsonNode.get("payload").size() == 0)) { ObjectNode objectNode = (ObjectNode) jsonNode; objectNode.putNull("payload"); } return mapper.treeToValue(jsonNode, type); } 

我相信我遇到了你记录的同样问题。

我收到了以下exception

 com.fasterxml.jackson.databind.JsonMappingException: Missing property 'content' for external type id 'contentType 

我最终通过将@JsonTypeId注释添加到类型字段来使其工作。

 public interface Content { } public class Post implements Content { public String content = "bar"; } public class Foo { @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "contentType") @JsonSubTypes({ @JsonSubTypes.Type(value = Post.class, name = "post") }) public Content content; @JsonTypeId public ContentType contentType; public enum ContentType { "post" } } 

这有明确的反序列化function:

 new ObjectMapper().configure( DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY, false);