使用Jackson序列化Map.Entry时出现问题 [英] Issue when serializing Map.Entry using jackson

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

问题描述

如果我尝试反序列化以下存储为字符串的类型:

 List<Entry<String, String>> entryList;

其中entry List包含:

[{"dummyKey1":"dummyValue1"}]

我收到以下错误

 Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.util.Map$Entry, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information.

在JUNIT中运行测试用例时出现上述错误,但如果删除测试用例,则在部署后一切运行正常:

由于条目中没有NoArgsConstructor,所以在运行junit测试用例时出现上述错误。因此,我使用NoArgsConstructor创建了一个DummyEntry,它使用参数作为空参数调用条目。

   DummyEntry<K, V> extends SimpleEntry<K, V>
进行此更改后,上面的错误没有出现,但在部署更改后,我开始出现下面的错误。

  Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
  Unrecognized field "dummyKey1", not marked as ignorable (2 known properties: "value", "key"]).

为什么一种方法不适用于JUNIT,但在生产中有效,而另一种方法在JUNIT中有效,但在生产中不起作用。

另外,我还注意到一件事:在生产中,Map.Entry被序列化为

  {'dummyKey1':'dummyValue1'}

而JUNIT中的测试用例将相同的字符串序列化为

 {'key':'dummyKey1', 'value':'dummyValue1'}

这种奇怪行为的原因是什么?我如何才能使这件事对两个人都起作用?

推荐答案

我怀疑您可能遇到了Map.Entry的不同序列化策略问题。

在Jackson的V2.5.0(IIRC)中-数据库Map.Entry was supported as a 'known type'。在此版本之前,Map.Entry的keyvalue属性将出现在序列化的Map.Entry中。在此版本之后,情况不再是这样。

以下是一些示例测试用例,说明了我的意思:

@Test
public void mapSerialisationPreJackson2_5_0() throws IOException {
  Map<String, String> aMap = Maps.newHashMap();
  aMap.put("dummyKey1", "dummyValue1");

  Set<Map.Entry<String, String>> incoming = aMap.entrySet();

  ObjectMapper objectMapper = new ObjectMapper();

  String serialised = objectMapper.writeValueAsString(incoming);

  // prints: [{"key":"dummyKey1","value":"dummyValue1"}]
  System.out.println(serialised);

  Set<Map.Entry<String, String>> deserialised = objectMapper.readValue(serialised, Set.class);

  // prints: [{key=dummyKey1, value=dummyValue1} (just like you posted in your question) whereas for versions > 2.5.0 the serialised form is ]
  System.out.println(deserialised);
}

@Test
public void mapSerialisationPostJackson2_5_0() throws IOException {
  Map<String, String> aMap = Maps.newHashMap();
  aMap.put("dummyKey1", "dummyValue1");

  Set<Map.Entry<String, String>> incoming = aMap.entrySet();

  ObjectMapper objectMapper = new ObjectMapper();

  String serialised = objectMapper.writeValueAsString(incoming);

  // prints: [{"dummyKey1":"dummyValue1"}]
  System.out.println(serialised);

  Set<Map.Entry<String, String>> deserialised = objectMapper.readValue(serialised, Set.class);

  // prints: [{dummyKey1=dummyValue1}]
  System.out.println(deserialised);
}

在v2.5.0之前,Map.Entry将被序列化为{key=dummyKey1, value=dummyValue1}(就像您在问题中发布的那样),而对于2.5.0以上的版本,序列化形式是{dummyKey1=dummyValue1}

我认为您在测试上下文中使用的是<;2.5.0版本的jackson-data ind,而在生产上下文中使用的是>2.5.0的jackson-data ind版本

这篇关于使用Jackson序列化Map.Entry时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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