Jackson:反序列化包含列表的泛型类型 [英] Jackson: deserializing a generic type that contains a list
问题描述
我希望从JSON反序列化的实体如下:
The entity that I am looking to deserialize from JSON is as follows:
public class TypedMemberDTO<T> {
private List<T> details;
private String type;
// Getters and setters
}
我知道 T
可能只是两个实际类别中的一个,具体取决于类型
属性的值。
I know that T
may only be one of two actual classes depending on the type
attribute's value.
我见过如何使用 objectMapper.readValue反序列化列表的例子(json,objectMapper.getTypeFactory()。collectionType(ArrayList.class,MyClass.class));
但是,我还没有看到任何关于如何实现上述目标的例子。
However, I haven't seen any examples on how to achieve what I'm looking to do above.
有人可以在反序列化我的课程时指出正确的方向吗?
Can someone please point me in the right direction on deserializing my class?
理想情况下,我想避免任何基于注释的方法,如果可能的话
Ideally I want to avoid any annotation based approach if that is possible
推荐答案
正如@fge在评论中建议的那样,您可以使用自定义反序列化器来实现此目的。
As @fge suggested in his comment, you can use a custom deserializer to achieve this.
假设 type
包含列表元素的完全限定类名,以下反序列化器将完成这项工作:
Assuming that type
contains the fully qualified class name of the elements of the list, the following deserializer will do the job:
public class TypedMemberDTODeserializer extends JsonDeserializer<TypedMemberDTO<?>> {
@Override
public TypedMemberDTO<?> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
try {
JsonNode rootNode = jp.getCodec().readTree(jp);
String type = rootNode.get("type").asText();
JavaType parametricListType = ctxt.getTypeFactory().constructParametricType(
List.class, Class.forName(type));
JsonNode detailsNode = rootNode.get("details");
List<?> detailsList = new ObjectMapper().readValue(detailsNode.toString(), parametricListType);
return new TypedMemberDTO(detailsList, type); // unchecked
} catch (ClassNotFoundException e) {
throw new IOException(e);
}
}
}
ObjectMapper
需要被告知反序列化器:
The ObjectMapper
needs to be informed about the deserializer:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new SimpleModule().addDeserializer(TypedMemberDTO.class,
new TypedMemberDTODeserializer()));
TypedMemberDTO<?> typedMemberDTO = objectMapper.readValue(jsonString, TypedMemberDTO.class);
我不知道这个解决方案的性能(它使用嵌入式反序列化器中的ObjectMapper
,您可能需要检查它。您可以在此处了解有关自定义反序列化器的更多信息。
I don't know the performance of this solution (it's using an embedded ObjectMapper
in the deserializer), you may have to check that. You can read more about custom deserializers here.
这篇关于Jackson:反序列化包含列表的泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!