Jackson对象映射器,用于将java映射转换为json,并保持键的顺序

Jackson对象映射器,用于将java映射转换为json,并保持键的顺序,java,json,jackson,Java,Json,Jackson,我正在使用jackson.map.ObjectMapperAPI将映射转换为json字符串。我使用writeValueAsString方法来实现这一点 我将根据值排序的映射传递给writeValueAsString方法。我得到的JSON字符串是基于键重新调用的 有没有一种方法可以使用jackson将映射转换为JSON字符串,而不影响映射中项目的顺序 我尝试将Feature.SORT\u PROPERTIES\u按字母顺序设置为false,但根据文档,它仅适用于POJO类型 实现上述行为的任何想法

我正在使用
jackson.map.ObjectMapper
API将映射转换为json字符串。我使用writeValueAsString方法来实现这一点

我将根据值排序的映射传递给
writeValueAsString
方法。我得到的JSON字符串是基于键重新调用的

有没有一种方法可以使用jackson将映射转换为JSON字符串,而不影响映射中项目的顺序

我尝试将
Feature.SORT\u PROPERTIES\u按字母顺序
设置为false,但根据文档,它仅适用于POJO类型

实现上述行为的任何想法。

对于Jackson 2.3.1(以前的版本不知道),您可以序列化SortedMap,例如TreeMap,顺序将得到遵守

以下是junit 4中的一个示例:

    @Test
public void testSerialize() throws JsonProcessingException{
    ObjectMapper om = new ObjectMapper();
    om.configure(SerializationFeature.WRITE_NULL_MAP_VALUES,false);
    om.configure(SerializationFeature.INDENT_OUTPUT,true);
    om.setSerializationInclusion(Include.NON_NULL);

    SortedMap<String,String> sortedMap = new TreeMap<String,String>();
    Map<String,String> map = new HashMap<String,String>();
    map.put("aaa","AAA");

    map.put("bbb","BBB");
    map.put("ccc","CCC");
    map.put("ddd","DDD");

    sortedMap.putAll(map);

    System.out.println(om.writeValueAsString(map));

    System.out.println(om.writeValueAsString(sortedMap));


}
用一张分类地图

{
  "aaa" : "AAA",
  "bbb" : "BBB",
  "ccc" : "CCC",
  "ddd" : "DDD"
}
`

将不会订购带有映射的第一个序列化, 第二个带有树映射的将使用键按字母顺序排列。您可以将一个比较器传递给不同顺序的树映射


编辑:它还可以在Jackson上使用LinkedHashMap(),即使这不是SortedMap。这是Map的一个实现,它保持键插入Map的顺序。这可能就是您要查找的内容。

通用映射不能保证键的顺序,因此我不知道如何才能做到这一点。您需要确保使用的映射保持插入顺序,即树映射而不是哈希映射。我只使用了树映射,并且值按我想要的方式排序。然而,当我通过树状图时(事实上是一个包含everal树映射的对象)到Jackson API要获取JSON字符串,我的所有映射值都是基于键重新调用的。如果我错了,请纠正我,但我不知道有什么方法可以正确创建一个按值排序的映射,该值与java SortedMap接口规范完全兼容。一个成对的SortedSet可以。但是map可以只需更新这样的地图上的值就可以制动所有的东西。比较值的比较器也会制动一些规则。请考虑使用配对集。谢谢你给我时间。我已经尝试了TrimAP和Link KeHasmap。我正在配置我的映射器,不使用下面的配置属性来对地图进行排序。.SORTED\u MAPPER.configure(SerializationConfig.Feature.SORT\u PROPERTIES\u字母顺序,false);当我将映射(treemap或链接的hashmap)传递给writeValueAsString方法时,此操作绝对正常,如下所示:SORTED\u MAPPER.writeValueAsString(map);但是,我有10个不同的映射要转换为JSON,因此我无法将map对象传递给此方法。因此,我将所有映射放在一个对象中,并将此对象作为SORTED_MAPPER.writeValueAsString(myObject)传递给该方法其中myObject包含所有映射;由于某种原因,Jackson API无法在这种情况下配置映射,并基于密钥使用所有映射。Jackson在某些边缘情况下有点问题,通常最好实现自己的序列化程序。()@MartinKersten是一个专门为Map定制的Jackson序列化程序,是的。有一瞬间我担心你会提议在没有任何库的情况下进行所有JSON序列化。你有关于edge案例的更多信息吗,它是否与Map序列化有关?有几个案例我支持的团队最终选择了定制序列化程序,或者当我我负责实现我们自己的JSON序列化机制。JSON相当简单,直接支持它很容易实现。我不喜欢注释和隐藏魔法。序列化直接涉及数据,数据是我们日常编程汤的主要成分。因此,我喜欢数据对象能够自身序列化,而不是“发现”如何序列化它。无论何时(模式)发生变化,事情都会变得混乱。所以自定义几乎总是最有效的。团队通常将其视为一种缓解。
{
  "aaa" : "AAA",
  "bbb" : "BBB",
  "ccc" : "CCC",
  "ddd" : "DDD"
}