Я создаю службу отдыха, используя jackson с одним экземпляром ObjectMapper, где я могу установить свою конфигурацию. Значения на стороне Java - это pojos с полями типа String и int. Очень простая, понятная ситуация, ничего особенного.

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

Конкретный пример: скажем, я хочу вызывать toUpperCase () для каждой входящей строки, потому что мне не нравятся строчные буквы. Как я могу создать такое поведение? Я надеялся найти что-то вроде следующего, но его, похоже, не существует:

objectMapper.getDeserializationConfig().registerValueProcessor(Foo.class, Foo::bar);

Я знаком с основами Джексона, такими как регистрация сериализатора нового типа (де), я просто ничего не знаю об этом конкретном типе вещей.

0
Marnes 14 Мар 2018 в 15:20

2 ответа

Лучший ответ

Я думаю, лучше всего было бы написать свой собственный (де) сериализатор impl, который обертывает существующий (де) сериализатор, используя наследование или композицию, и заменяет его в конфигурации objectmapper. Таким образом, я могу вызвать исходную логику преобразования (через super или поле) и обработать полученный результат.

0
Marnes 14 Мар 2018 в 23:47

Конкретный пример: скажем, я хочу звонить toUpperCase() при каждом входящем String, потому что мне не нравятся строчные буквы. Как я могу создать такое поведение?

Создайте свой собственный десериализатор для String:

SimpleModule module = new SimpleModule("customDeserializers", Version.unknownVersion());
module.addDeserializer(String.class, new StdDeserializer<String>(String.class) {

    @Override
    public String deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        return jp.getValueAsString().toUpperCase();
    }
});

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);

Пользовательский десериализатор, определенный выше, будет обрабатывать только значения, сопоставленные с String. Если данный POJO имеет член, тип которого, например, UUID, значение не будет преобразовано в верхний регистр. См. Пример ниже:

public class Person {

    private UUID id;

    private String name;

    // Getters and setters
}
String json = "{\"id\": \"6d39b716-ee80-4468-b1e4-b4270d57be99\", \"name\": \"Joe Doe\"}";
Person person = mapper.readValue(json, Person.class);

System.out.println(person.getId());   // Prints 6d39b716-ee80-4468-b1e4-b4270d57be99
System.out.println(person.getName()); // Prints JOE DOE
0
cassiomolin 14 Мар 2018 в 13:25