拥有像下一个一样的动态POJO:
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MyDynamicWrapper <T> {
@JsonProperty("header")
private CommonHeader header;
@JsonProperty("payload")
private T payload;
public MyDynamicWrapper(CommonHeader header, T payload) {
super();
this.header = header;
this.payload = payload;
}
public CommonHeader getHeader() {
return header;
}
public void setHeader(CommonHeader header) {
this.header = header;
}
public T getPayload() {
return payload;
}
public void setPayload(T payload) {
this.payload = payload;
}
}
T
有效负载可以是以下之一:
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MyPayloadOne {
@JsonProperty("status")
private int status;
@JsonProperty("action")
private String action;
...
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MyPayloadTwo {
@JsonProperty("properties")
private List<String> properties = new ArrayList<>();
...
}
杰克逊对这些动态信息进行反序列化的最佳方法是什么?是否必须实现反序列化器?我当前的配置不是动态的,我正在使用:
MyDynamicWrapper pojo = jacksonMapper.readValue(jsonMessage, MyDynamicWrapper.class);
我认为这是如此明显,但我不知道如何表明杰克逊的动态参考。
更新
除了接受的答案,我还检查过可以像这样定义杰克逊映射器:
MyDynamicWrapper<?> pojo = jacksonMapper.readValue(jsonMessage, MyDynamicWrapper.class);
这会将POJO转换为两个有效负载。
答案 0 :(得分:1)
You can (and should) pass a TypeReference to readValue
to specify the type of generic class instance you want to deserialize. E.g. when wrapping MyPayloadOne
:
TypeReference ref = new TypeReference<MyDynamicWrapper<MyPayloadOne>>(){};
MyDynamicWrapper<MyPayloadOne> pojo = jacksonMapper.readValue(jsonMessage, ref);
答案 1 :(得分:0)
您需要通过实施this类来编写自定义序列化程序。或Deserializer
答案 2 :(得分:0)
尝试使用此问题中指定的@JsonCreator和@JsonProperty。 Is Jackson really unable to deserialize json into a generic type?
杰克逊需要更多的帮助来确定要反序列化的类型,这就是那些注释有助于做的事情。
答案 3 :(得分:0)
如果您在编译时知道类型参数,那么您可以使用TypeReference
反序列化JSON,如接受的答案中所述。
如果在编译时未知类型参数,那么即使这样也可以反序列化JSON。要实现这一点,您需要在可以作为类型参数传递给通用MyDynamicWrapper<T>
的所有类上放置某些Jackson注释。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonTypeName("MyPayloadOne")
public class MyPayloadOne {
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonTypeName("MyPayloadTwo ")
public class MyPayloadTwo {
}
现在,当您将使用MyDynamicWrapper
或MyPayloadOne
创建的MyPayloadTwo
实例反序列化为参数时,Jackson会将类型参数信息放入JSON中。然后可以将此JSON反序列化为泛型类MyDynamicWrapper.class,就像反序列化任何其他类一样,即,
无需指定类型参数(MyPayloadOne
或MyPayloadTwo
)。
MyDynamicWrapper<?> pojo = jacksonMapper.readValue(jsonString, MyDynamicWrapper.class);
请参阅Polymorphic Deserialization和Annotations上的杰克逊文档。