我希望从JSON反序列化的实体如下:
public class TypedMemberDTO<T> {
private List<T> details;
private String type;
// Getters and setters
}
我知道T
可能只是两个实际类别中的一个,具体取决于type
属性的值。
我已经看过如何使用objectMapper.readValue(json, objectMapper.getTypeFactory().collectionType(ArrayList.class, MyClass.class));
但是,我还没有看到任何关于如何实现我上面要做的事情的例子。
有人可以在反序列化我的课程时指出正确的方向吗?
理想情况下,如果可能的话,我想避免任何基于注释的方法
答案 0 :(得分:3)
正如@fge在评论中建议的那样,您可以使用自定义反序列化器来实现此目的。
假设type
包含列表元素的完全限定类名,以下反序列化器将完成这项工作:
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
需要了解解串器:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new SimpleModule().addDeserializer(TypedMemberDTO.class,
new TypedMemberDTODeserializer()));
TypedMemberDTO<?> typedMemberDTO = objectMapper.readValue(jsonString, TypedMemberDTO.class);
我不知道此解决方案的性能(它在反序列化程序中使用嵌入式ObjectMapper
),您可能需要检查它。您可以阅读有关自定义反序列化程序here的更多信息。