我想知道是否可以使用Jackson的JsonSerializer生成JSON对象,其中属性按值排序(而非按键排序)。例如:
{
"property2": 320,
"property1": 287,
"property4": 280,
"property3": 123,
...
}
我尝试生成它,创建一个自定义的JsonSerializer,如下所示:
public class MySerializer extends JsonSerializer<Map<String, Long>> {
@Override
public void serialize(Map<String, Long> t, JsonGenerator jg, SerializerProvider sp) throws IOException, JsonProcessingException {
List<Entry<String, Long>> list = new ArrayList<>(t.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Long>> () {
@Override
public int compare(Map.Entry<String, Long> o1, Map.Entry<String, Long> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
jg.writeStartObject();
for(Entry<String, Long> entry : list) {
jg.writeNumberField(entry.getKey(), entry.getValue());
}
jg.writeEndObject();
}
}
但是生成的JSON没有按属性值排序,杰克逊必须再次扰乱对象属性。有没有办法实现这个目标?
编辑:问题不在于Jackson,而是我用来检索JSON(CocoaRestClient)的应用程序,它改变了生成对象中属性的顺序。我的方法和@ m.aibin的方法都是正确的。 如果您遇到类似问题,请检查问题不是您用来检索JSON的应用程序。
答案 0 :(得分:1)
您可以对地图进行排序,然后对其进行序列化。使用Jackson 2.3.1,您可以序列化SortedMap,例如LinkedHashMap,订单将得到尊重。
链接如何对哈希映射进行排序例如:Sorting HashMap by values
答案 1 :(得分:1)
我开发了Jersey 2
java服务,用于前端使用Angular 2/4
,用于测试用过的Advanced Rest Client
,用于数据序列化使用Jackson
Java框架,在服务器端我用过LinkedHashMap<Integer, Object>
,即Map,它保持了插入顺序,我使用自定义Jackson
序列化程序序列化了该映射,原始字符串包含有序JSON map
,但是在我使用{{1}之后使用该服务我看到,Advanced Rest Client
取消了我的排序,即使原始响应已经排序,Advanced Rest Client
也是如此。
这是因为我们违反Angular 2/4
的规范,声称JSON
或其他字Json object
是无序集。 Json map
中订购的内容为Json
,因此我最终发送了Json array
与已订购密钥的Json Map
,因此我必须在{{1}上查看该数组方面是为了从Json Array
重新创建订单。
<强> TL; DR 强>
无需对Angular
进行排序,您也不应该这样做,只需在Json Map
中保持按键顺序。