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