使用Jackson自定义反序列化列表 [英] Custom deserialization of List using Jackson

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

问题描述

我正在尝试编写一个自定义反序列化器,以减少从其他地方收到的大量数据.我从反序列化器返回一个自定义对象列表.

I am trying to write a custom deserializer in order to trim down a big set of data I receive from somewhere else. I return a List of custom objects from the deserializer.

我的问题是,如果这是我的自定义反序列化器,该怎么办:

My question is, how do I do that, if this is my custom deserializer :

public class MyCustomDeserializer extends JsonDeserializer<List<CustomClass>> { ... }

我当然不能这样做:

final SimpleModule module = new SimpleModule();
module.addDeserializer(List<CustomClass>.class, new MyCustomDeserializer());

这样的作品有用吗?

final List<CustomClass> response = Arrays.asList(objectMapper.readValue(stringBean, CustomClass[].class));

如果这确实可行,我会感到困惑和危险"吗?反序列化不是在asList方法调用内完成的吗?因此,它基本上将List映射到array []吗?

If this indeed works, I find it a bit confusing and "dangerous" ? Isn't the deserialization done inside the asList method invocation ? So it basically maps a List to an array[] ?

我了解了TypeReference,因此我可以像这样使用它:

I learned about TypeReference so I can probably use that like so :

objectMapper.readValue(stringBean, new TypeReference<List<CustomClass>>(){});

但是我听说它慢一些.

我也不想为列表创建一个容器,并在反序列化中将其返回,因为这意味着它将被包装在另一个json对象中,我只是希望我的端点产生类似以下内容的东西:

I also don't want to create a container for the list, and return that in the deserialization because that means it will be wrapped in another json object, and I simply want my endpoint to produce something like :

[{object1}, {object2}]

// instead of

{"Output" : [{object1}, {object2}]}

在这两种情况下,我似乎都误解了杰克逊如何使用我的解串器:

It seems that I have misinterpreted how jackson is using my deserializer in both cases :

final List<CustomClass> response = Arrays.asList(objectMapper.readValue(stringBean, CustomClass[].class));
// or
objectMapper.readValue(stringBean, new TypeReference<List<CustomClass>>(){});

看起来解串器被调用了两次,一次针对数组中的每个对象.我认为整个阵列将被视为一个整体.为了消除混乱,这是我的意思:

It looks like the deserializer is called twice, once for each object in the array. I thought that the entire array would be considered as a whole. To clear the confusion, here is what I mean:

我收到并尝试反序列化的json看起来像这样:

The json I receive and try to deserialize looks like so :

[
  {
    "Data" : {
      "id" : "someId",
      "otherThing" : "someOtherThing"
    },
    "Message" : "OK"
  },
  {
    "Data" : null,
    "Message" : "Object not found for id blabla"
  }
]

所以我虽然这是我在反序列化器中所拥有的,但是正如我之前说过的那样,看来我实际上是从该数组中获取每个入口"并多次调用它.

and so I though this is what I would have inside my deserializer, but as I said before it seems that i actually get each "entry" from that array and call it multiple times.

推荐答案

首先,如果您使用Bean CustomClass上的注释注册了自定义反序列化器,则该反序列化器应处理CustomClass的一个实例而不是一个集合.因此应该定义:

First of all, If you registered your custom deserializer using annotation on the bean CustomClass then the deserializer should handle one instance of CustomClass and not a collection and thus should be defined:

public class MyCustomDeserializer extends JsonDeserializer<CustomClass> {
        @Override
        public CustomClass deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException
        {
            ...
        }
}

现在您可以使用Jackson的类型工厂向映射器传递所需的类型信息

and now you can use Jackson's type factory to pass the mapper the required type information

JavaType customClassCollection = objectMapper.getTypeFactory().constructCollectionType(List.class, CustomClass.class);
List<CustomClass> beanList = (List<CustomClass>)objectMapper.readValue(stringBean, customClassCollection);

这篇关于使用Jackson自定义反序列化列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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