首页 > 解决方案 > 如何使用 JSON 以声明顺序序列化带有枚举键的映射?

问题描述

我有一些枚举类,让我们想象一下

public enum MyEnum {
    ONE("one"), TWO("two"), THREE("three"), DEFAULT("some value")
    //..
}

和 Dto 类:

@JsonPropertyOrder(value = {"id", "name", "params"})
public Dto {
    private Long id;
    private String name;
    private Map<MyEnum, Object> params;
}

如何设置参数映射中的顺序?我知道 LinkedHashMap 可用于设置顺序并以正确的顺序添加到地图中。但!在某些情况下,应该在运行时添加键值,并且应该将其添加到参数映射而不是最后一个链接,而是在映射内部。例如

params = new LinkedHashMap();
params.put(ONE, new String("object1"));
params.put(THREE, new String("object #3"));

而不是在我们刚刚添加的另一个代码位置

params.put(TWO, new Integer(20));

json里面的顺序应该是:

{
 "id":"123", "name":"some name", 
"params":{"ONE":"object1","TWO":"20","THREE":"object #3"}
 }

标签: javajsonjacksonobjectmapperjson-serialization

解决方案


MapSerializer我可以建议两个选项,它们都依赖于 Jackson 使用 a来序列化 type 对象这一事实Map

首先,由于enum类型根据它们的声明顺序定义了一个隐式的自然顺序,你可以启用你ObjectMapperSerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS. javadoc 指出,

确定java.util.Map条目是否在序列化之前首先按键排序的功能:如果启用,则在必要时执行额外的排序步骤(对于 java.util.SortedMaps 不是必需的),如果禁用,则不需要额外的排序。

换句话说,您的params地图中的枚举将首先按其声明顺序排序,然后才进行序列化。请注意,此序列化功能适用于所有地图。

其次,您可以初始化paramsEnumMap. 要序列化 ​​a MapMapSerializer迭代地图的entrySet(). 返回的条目集按照对应类型EnumMap#entrySet()中常量的声明顺序排序。enum你会有

params = new EnumMap<>(MyEnum.class);
params.put(THREE, new String("object #3"));
params.put(ONE, new String("object1"));
// whatever order

Jackson 将按照枚举常量的声明顺序对它们进行序列化。


推荐阅读