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.



например: один раз это было бы



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


а в другой раз было бы



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


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



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

761   6  

6 ответов:

С Джексон аннотации документация:

// 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 для работы таким образом с

текущие версии Джексона : objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)

старые версии Джексона : objectMapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true);

в Spring Boot вы можете добавить это поведение глобально, добавив следующее к вашему 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 для XMLs и поставляется с jackson-databind, который не требуется...

В Джексоне 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"
  }
}

Comments

    Ничего не найдено.