2014-10-16 139 views
1

,我期待从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

我不认为这是可能的(由于类型擦除) – 2014-10-16 17:25:45

回答

3

由于@fge在他的评论所说,你可以使用自定义解串器来实现这一目标。

假设type包含列表中的元素的完全限定类名,下面的解串器将做的工作:

 ObjectMapper objectMapper = new ObjectMapper(); 
     objectMapper.registerModule(new SimpleModule().addDeserializer(TypedMemberDTO.class, 
       new TypedMemberDTODeserializer())); 
     TypedMemberDTO<?> typedMemberDTO = objectMapper.readValue(jsonString, TypedMemberDTO.class); 

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),您可能需要检查一下。你可以阅读更多关于定制解串器here