Как сериализовать карту с enum-ключами в порядке объявления с помощью JSON?

У меня есть некоторый enum класс, давайте представим

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"}
 }

1 ответ

Решение

Я могу предложить два варианта, которые основаны на том факте, что Джексон использует MapSerializer сериализовать объекты типа Map,

Во-первых, так как enum типы определяют неявный естественный порядок на основе их порядка объявления, вы можете включить ObjectMapper"s SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, Javadoc утверждает,

Функция, которая определяет, является ли java.util.Map Записи сначала сортируются по ключу перед сериализацией или нет: если включено, дополнительный шаг сортировки выполняется при необходимости (не обязательно для java.util.SortedMaps) если отключено, дополнительная сортировка не требуется.

Другими словами, перечисления в вашем params Сначала карта будет отсортирована по порядку объявления, а затем сериализована. Обратите внимание, что эта функция сериализации применяется ко всем картам.

Во-вторых, вы можете инициализировать params как EnumMap, Сериализовать Map, MapSerializer повторяет карту entrySet(), Набор записей, возвращаемый EnumMap#entrySet() упорядочен по порядку объявления констант в соответствующих enum тип. Вы бы имели

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

и Джексон будет сериализовать их в порядке объявления констант перечисления.

Другие вопросы по тегам