【问题标题】:Jackson Java to JSON object mapper modifies field's nameJackson Java 到 JSON 对象映射器修改字段名称
【发布时间】:2018-01-12 09:36:42
【问题描述】:

使用 Jackson 将 Java 对象转换为 JSON

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
jsonMessage = mapper.writeValueAsString(object);

结果是字段“参与者”(它是对象实例的一部分)

participants    Arrays$ArrayList<E> 

重命名为“participantsList”

participantsList":[{"userId":"c1f9c"}]

即“列表”附加到字段名称。我浏览了杰克逊的文档,但还没有找到防止这种情况发生的方法。这可能吗?在独立项目中测试上述代码不会导致相同的结果(即不发生重命名)。为什么杰克逊会有这样的行为?不幸的是,该对象是第三方的,我无法更改它。

使用 Jackson 2.3.3 版(与 2.9.0 验证的行为相同)。

【问题讨论】:

  • 什么是消息对象?
  • 作为 writeValueAsString() 的参数传递的实例。它是一个第三方对象,所以不能在那里做太多事情。
  • 如果它是第三方对象,那么您应该创建一个您控制的模型以进行序列化。然后您将转换第三方对象并序列化为 JSON。这样您就可以根据自己的意愿注释所有属性。
  • 你能验证一下吗,可能有一个对应的getter叫做getParticipantsList()
  • @OleksandrShpota 已经发现了问题。还有一个问题讨论如何使用基于字段而不是方法的杰克逊序列化:stackoverflow.com/questions/10240372/…

标签: java json jackson objectmapper


【解决方案1】:

Oleksandr 的评论指出了正确的方向。事实上,杰克逊在确定 JSON 字段名称时似乎考虑了一个 getParticipantsList()。但是,正如我之前写的,考虑到它是第三方对象,我无法在那里进行任何更改。

但是,随着对导致问题的原因有了更好的了解,我能够想出一个解决方案:

mapper.setVisibilityChecker(mapper.getVisibilityChecker().withFieldVisibility(Visibility.ANY).withGetterVisibility(Visibility.NONE).withIsGetterVisibility(Visibility.NONE));

mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.setVisibility(PropertyAccessor.GETTER, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.NONE);

【讨论】:

  • 您没有使用 Jackson 2.6+,因此此评论与您无关,但可能与其他人有关:setVisibilityChecker 自 2.6 起已弃用。您必须改用 setVisibility 。 fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/…
  • @JuniorDussouillez 我实际上只是出于同样的目的编辑我的答案!我刚刚在以后的版本中发现了所说的弃用。无论如何,感谢您指出!
  • 澄清一下,您的对象的字段和吸气剂命名不匹配(杰克逊默认使用吸气剂名称)?
  • 您可以使用mix-ins 将杰克逊注解应用于您无权更改的类。
  • @CodeConfident 正确 - 虽然我不确定我们是否可以称它们不匹配,而且不遵循通常的约定。
【解决方案2】:

也许您可以使用 USE_ANNOTATIONS 来跳过这样的注释:

    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    mapper.configure(MapperFeature.USE_ANNOTATIONS, false);
    String jsonMessage = mapper.writeValueAsString(object);

【讨论】:

  • 这并没有达到预期的效果;仍会附加“列表”后缀。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多