Jackson:反序列化包含列表的泛型类型 [英] Jackson: deserializing a generic type that contains a list

查看:154
本文介绍了Jackson:反序列化包含列表的泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆