使用 @JsonSubTypes 反序列化没有值 - 缺少 属性 错误
Deserialization with @JsonSubTypes for no value - missing property error
我这样反序列化 json:
{
"type":"a",
"payload" : {...}
}
其中负载类型取决于类型。我的 class:
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",
}
如何让它与上一个示例一起工作?
我得到的错误堆栈跟踪:
[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)
我相信我遇到了与您记录的相同的问题。
我收到以下异常
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"
}
}
我也遇到过这个问题,无法使用 Jackson 提供的机制(自定义 BeanDeserializer
、BeanDeserializerModifier
等)找到优雅的解决方案。
这看起来像是处理外部类型 ID 的方式中的错误。我通过以下方式解决了这个问题:
- 将 JSON 字符串反序列化为
JsonNode
;
- 如果所需的 属性 不存在,则手动插入
null
节点;
- 将
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);
}
有明确的反序列化功能:
new ObjectMapper().configure(
DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY,
false);
我这样反序列化 json:
{
"type":"a",
"payload" : {...}
}
其中负载类型取决于类型。我的 class:
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",
}
如何让它与上一个示例一起工作?
我得到的错误堆栈跟踪:
[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)
我相信我遇到了与您记录的相同的问题。
我收到以下异常
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"
}
}
我也遇到过这个问题,无法使用 Jackson 提供的机制(自定义 BeanDeserializer
、BeanDeserializerModifier
等)找到优雅的解决方案。
这看起来像是处理外部类型 ID 的方式中的错误。我通过以下方式解决了这个问题:
- 将 JSON 字符串反序列化为
JsonNode
; - 如果所需的 属性 不存在,则手动插入
null
节点; - 将
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);
}
有明确的反序列化功能:
new ObjectMapper().configure(
DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY,
false);