Глобальные настройки Джексона для десериализации массива для реализации пользовательского списка

Вероятно, вы должны пойти с лямбдой ради удобочитаемости. Но как интересное исследование функций более высокого порядка, вот расширенная версия q-combinator в Python (также известная как компилятор странных птиц). Это позволяет вам создать новую функцию, составив две функции

 def compose(inner_func, *outer_funcs):
     if not outer_funcs:
         return inner_func
     outer_func = compose(*outer_funcs)
     return lambda *args, **kwargs: outer_func(inner_func(*args, **kwargs))

 from operator import itemgetter, methodcaller
 name_lowered = compose(itemgetter('name'), methodcaller('lower'))
 print(name_lowered( {'name': 'Foo'} ))

. Если вы измените определения внутреннего и внешнего в функции compose, вы получите более традиционный b-combinator (bluebird). Мне больше нравится q-combinator из-за сходства с Unix-каналами.

4
задан CrashBandicoot 18 January 2019 в 15:46
поделиться

2 ответа

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

Но я не уверен =))

0
ответ дан ZhenyaM 18 January 2019 в 15:46
поделиться

Общее решение - использовать пользовательский модуль. Вы можете определить классы, которые вы хотели бы использовать для коллекций. Для Гуавы есть модуль Maven:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-guava</artifactId>
    <version>x.y.z</version>
</dependency>

Теперь вы можете зарегистрировать свой новый модуль:

ObjectMapper mapper = new ObjectMapper();
// register module with object mapper
mapper.registerModule(new GuavaModule());

Теперь вы можете указать в своем POJO, что вы хотите иметь неизменяемый выполнение списка.

class Pojo {

    private ImmutableList<Integer> ints;

    public ImmutableList<Integer> getInts() {
        return ints;
    }

    public void setInts(ImmutableList<Integer> ints) {
        this.ints = ints;
    }

    @Override
    public String toString() {
        return "Pojo{" +
                "ints=" + ints + " " + ints.getClass() + '}';
    }
}

и ниже пример:

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

String json = "{\"ints\":[1,2,3,4]}";

System.out.println(mapper.readValue(json, Pojo.class));

печатает:

Pojo{ints=[1, 2, 3, 4] class com.google.common.collect.RegularImmutableList}

Если вы не хотите связывать свои классы POJO с реализацией List, вам нужно добавьте дополнительную конфигурацию, используя класс SimpleModule. Итак, ваш POJO выглядит следующим образом:

class Pojo {

    private List<Integer> ints;

    public List<Integer> getInts() {
        return ints;
    }

    public void setInts(List<Integer> ints) {
        this.ints = ints;
    }

    @Override
    public String toString() {
        return "Pojo{" +
                "ints=" + ints + " " + ints.getClass() + '}';
    }
}

, а ваш пример выглядит следующим образом:

SimpleModule useImmutableList = new SimpleModule("UseImmutableList");
useImmutableList.addAbstractTypeMapping(List.class, ImmutableList.class);

GuavaModule module = new GuavaModule();

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

String json = "{\"ints\":[1,2,3,4]}";

System.out.println(mapper.readValue(json, Pojo.class));

Выше кода печатается:

Pojo{ints=[1, 2, 3, 4] class com.google.common.collect.RegularImmutableList}

Когда вы удалите лишние SimpleModule отпечатки кода выше:

Pojo{ints=[1, 2, 3, 4] class java.util.ArrayList}

Я не вижу смысла использовать Collections.emptyList(), если он пуст. Модуль Guava использует RegularImmutableList для непустых и пустых массивов.

Для преобразования null -> empty см. Этот вопрос:

  1. Джексоновский десериализатор - изменить пустую коллекцию на пустую

, но я рекомендуем установить его на empty в POJO, как показано ниже:

private List<Integer> ints = Collections.emptyList();
0
ответ дан Michał Ziober 18 January 2019 в 15:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: