Jackson ObjectMapper – указать порядок сортировки свойств объекта

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

Ток подтверждения – это объект VerifData, сериализованный в строку, а затем hashированный и зашифрованный.

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 Security API для подписи и проверки.

Из документации 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) 

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

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

Старые версии jacksonа: objectMapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true);

В Spring Boot вы можете добавить это поведение глобально, добавив следующее в class точки входа в Application :

  @Bean public Jackson2ObjectMapperBuilder objectMapperBuilder() { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.featuresToEnable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY); return builder; } 

В Spring Boot есть более простой способ, указав свойство (в application.properties например:

 spring.jackson.mapper.sort_properties_alphabetically=true 

Из ответа Дункана Макгрегора: лучше использовать его так:

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

поскольку MapperFeature предназначен для XML-файлов и поставляется с джексоном-databind, который не требуется …

В 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" } } 
  • Сериализация типа Json.Net с полиморфным дочерним объектом
  • Каковы различия между XmlSerializer и BinaryFormatter
  • StackOverflowError при сериализации объекта в Java
  • Сериализация JSON массива с полиморфными объектами
  • Как десериализовать объект JObject для .NET
  • Как вы делаете глубокую копию объекта в .NET (например, C #)?
  • Можете ли вы определить, был ли объект, десериализованный объект, отсутствием поля с classом JsonConvert в Json.NET
  • Сериализация classа, который содержит std :: string
  • Исключение «Исключительная привязка к реляционной ссылке» с JSON.Net
  • Почему java.util.Optional не является Serializable, как сериализовать объект с такими полями
  • Java: объект для байта и байт для конвертера объектов (для Tokyo Cabinet)
  • Давайте будем гением компьютера.