Jackson ObjectMapper - указывает порядок сериализации свойств объектов

Я реализую УСПОКОИТЕЛЬНЫЙ веб-сервис, куда пользователь должен отправить маркер проверки со знаком наряду с запросом так, чтобы я мог удостовериться, что запрос не вмешался средним человеком. Моя текущая реализация следующие.

Маркер проверки является объектом VerifData, сериализированным в Строку и затем хешированным и зашифрованным.

class VerifData {
    int prop1;
    int prop2;
}

В моем сервисе я поместил данные, которые будут сериализированы в экземпляр VerifData и затем сериализируют его с помощью Jackson ObjectMapper, и передал механизму проверки наряду с маркером проверки.

VerfiData verifData = new VerifData(12345, 67890);
ObjectMapper mapper = new ObjectMapper();
String verifCodeGenerated = mapper.writeValueAsString(verifData);

Но кажется, что каждый раз контейнер приложения запускается, порядок свойств, отображаемых в строку изменениями ObjectMapper.

Исключая: одно время это было бы

{"prop1":12345,"prop2":67890}

и другое время это было бы

{"prop2":67890,"prop1":12345}

Таким образом, если клиент сериализировал экземпляр VerifData как в первую Строку, существует 50%-й шанс его отказавший даже при том, что это корректно.

Существует ли способ обойти это? Я могу указать порядок свойств отобразиться ObjectMapper (как в порядке возрастания)? Или есть ли любой другой способ лучше всего реализовать этот шаг проверки. Обе реализации клиента и сервера разрабатываются мной. Я использую безопасность Java API для подписания и проверки.

62
задан 20 December 2014 в 09:32

7 ответов

От документация Jackson Annotations :

// ensure that "id" and "name" are output before other properties
@JsonPropertyOrder({ "id", "name" })

// order any properties that don't have explicit setting using alphabetic order
@JsonPropertyOrder(alphabetic=true)
65
ответ дан 31 October 2019 в 13:28

Аннотации полезны, но могут быть болью для применения везде. Можно настроить целый ObjectMapper для прокладывания себе путь с

Текущие версии Jackson: objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)

Более старые версии Jackson: objectMapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true);

70
ответ дан 31 October 2019 в 13:28

В Начальной загрузке Spring можно добавить это поведение глобально путем добавления следующего к Вашему Application класс точки входа:

  @Bean
  public Jackson2ObjectMapperBuilder objectMapperBuilder() {

    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.featuresToEnable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);

    return builder;
  }
8
ответ дан 31 October 2019 в 13:28

Существует более легкий путь в Начальной загрузке Spring путем определения свойства (в application.properties, например:

spring.jackson.mapper.sort_properties_alphabetically=true
8
ответ дан 31 October 2019 в 13:28

Из ответа Duncan McGregor: лучше для использования его как это:

objectMapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true);

, поскольку MapperFeature для XMLs и идет с jackson-привязкой-данных, которая не требуется...

3
ответ дан 31 October 2019 в 13:28

В Jackson 2.x, который Вы, вероятно, используете сегодня, используйте:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

, Если Вы заботитесь о взглядах, можно также рассмотреть SerializationFeature.INDENT_OUTPUT также.

Примечание, которое необходимо сериализировать Объекты Карт или , чтобы это отсортировало правильно. Если Вы сериализируете JsonNode, например (от readTree), который не будет правильно расположен с отступом.

Пример

import com.fasterxml.jackson.databind.*;

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);

String input = "{\"hello\": {\"cruel\" : \"world\"} }";
Object pojo = mapper.readValue(input, Object.class);
System.out.println(mapper.writeValueAsString(pojo));

результаты в:

{
  "hello" : {
    "cruel" : "world"
  }
}
3
ответ дан 31 October 2019 в 13:28

Вместо того, чтобы использовать аргумент флага:

objectMapper.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY);
0
ответ дан 31 October 2019 в 13:28

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

Похожие вопросы: