使用Jackson

时间:2015-12-09 10:35:18

标签: java json jackson deserialization

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

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

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));

如果这确实有效,我觉得它有点令人困惑,而且很危险&#34; ?是不是在asList方法调用中完成了反序列化?所以它基本上将List映射到数组[]?

我了解了TypeReference,所以我可以这样使用它:

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

但我听说它慢了。

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

[{object1}, {object2}]

// instead of

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

修改

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

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

看起来反序列化器被调用两次,对于数组中的每个对象一次。我认为整个阵列将被视为一个整体。为了清除这种混淆,我的意思是:

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

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

所以我虽然这是我在反序列化器中的内容,但正如我之前所说的那样,我实际上得到了每个&#34;条目&#34;从该数组中多次调用它。

2 个答案:

答案 0 :(得分:10)

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

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

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

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

答案 1 :(得分:0)

我通过在模型类的属性中添加自定义反序列化器并使用JsonDeserialize注释的contentUsing()方法来解决此问题,如下所示:

@JsonDeserialize(contentUsing = MyCustomDeserializer.class)
private List<CustomClass> customClassObjList;

其中MyCustomDeserializer类是自定义的Jackson JSON解串器,定义为:

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