我像这样反序列化jsons:
{
"type":"a","payload" : {...}
}
有效负载类型取决于类型.我的课:
public class Sth<T extends Payload> {
@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提供的机制(自定义BeanDeserializer,BeanDeserializerModifier等)找不到优雅的解决方案.
它看起来像处理外部类型ID的方式中的错误.我解决了以下问题:
>将JSON tring反序列化为JsonNode;
>如果不存在required属性,则手动插入空节点;
>将JsonNode映射到我想要的值类型.
我的代码如下所示:
public <T> T decode(String json,Class<T> 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);
}