Подтвердить что ты не робот

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

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

Ток подтверждения - это объект 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.

Ex: один раз это будет

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

а в другой раз это будет

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

Итак, если клиент сериализовал экземпляр VerifData, как в первую строку, существует 50% вероятность его провала, даже если это правильно.

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

4b9b3361

Ответ 2

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

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

Ответ 3

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

  @Bean
  public Jackson2ObjectMapperBuilder objectMapperBuilder() {

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

    return builder;
  }

Ответ 4

В Spring загрузке проще, указав свойство (в application.properties например:

spring.jackson.mapper.sort_properties_alphabetically=true

Ответ 5

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

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

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

Ответ 6

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