JavaRush/Java блог/Random/Введение в Jackson Framework
Mikhail Fufaev
35 уровень

Введение в Jackson Framework

Статья из группы Random
участников
Холодной весенней ночью я наконец-таки перешел на 33 уровень. Потирая свои программистские ручки, я уже готовился объять всю сферу сериализации, десериализации JSON, но, к сожалению, ничего не понял. Текст лекции не запомнился, а задачи решались как-то интуитивно. В связи с этим решил полезть в дебри Jackson Framework и разобраться, что же такое этот JSON.
Jackson Framework
Все свои познания постараюсь изложить практико-ориентированно и лаконично в формате шпаргалки (как для себя, так и для читателей). Путешествие в Jackson Annotations. Первое, что мы встречаем на пути в JSON — это аннотация @JsonAutoDetect. На первый взгляд легкая аннотация, но с ней автору пришлось разбираться дольше всего. Аннотация имеет 5 нужных нам методов:
  • fieldVisibility() - сериализует поля только с указанным модификатором доступа
  • getterVisibility()/setterVisibility() - сериализует поля, у которых геттер/сеттер имеет указанный модификатор доступа
  • isGetterVisibility() - отдельная реализация для булевских геттеров
Важно понимать, что методы работают дизъюнктивно. Т.е. если поле соответствует хотя бы одному из указанных в аннотации параметров, то оно попадет в JSON. Попытайтесь ответить, что выведет данный код, если мы создадим экземляр, используя конструктор без параметров:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY,
        getterVisibility        = JsonAutoDetect.Visibility.PUBLIC_ONLY,
        setterVisibility        = JsonAutoDetect.Visibility.PUBLIC_ONLY,
        isGetterVisibility      = JsonAutoDetect.Visibility.PROTECTED_AND_PUBLIC)
public class HeadClass {
    public String name;
    private Map<String, String> properties;
    public Queue<String> queue;
    protected List<String> list;
    private int age;
    private int number;
    private boolean isHead;

    protected HeadClass(int age) {
        this.age = age;
    }

    public HeadClass() {}

    Map<String, String> getProperties() {
        return properties;
    }

    protected boolean isHead() {
        return isHead;
    }

    protected void setProperties(Map<String, String> properties) {
        this.properties = properties;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }
}
А если убрать isGetterVisibility? Четыре перечисленных метода конфигурировали процесс сериализации. Пятый же в свою очередь регулирует процесс десериализации:
  • creatorVisibility() - самый сложный метод для понимания. Он работает с конструкторами и с фабричными методами (методы, которые создают объект при обращении к ним). Рассмотрим пример:
@JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.PROTECTED_AND_PUBLIC)
public class HeadClass {
    public String name;
    public int id;

    HeadClass(@JsonProperty(value = "name") String name, @JsonProperty(value = "id") int id) {
        this.name = name;
        this.id = id;
    }

    protected HeadClass(String name) {
        this.name = name;
        this.id = 123;
    }

    protected HeadClass(int id) {
        this.id = id;
        this.name = "Yes!";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public static void main(String[] args) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    String forDeserialize = "{\"name\":\"No!\",\"id\":123}";
    StringReader reader = new StringReader(forDeserialize);

    HeadClass headClass1 = (HeadClass) mapper.readValue(reader, HeadClass.class);
}
Важное замечание по механизму десериализации! Когда мы пытаемся создать объект из JSON, то будет осуществляться поиск конструктора требуемого класса с таким же набором параметров, что и в JSON объекте. В примере выше наш JSON объект состоит из двух параметров: name, id. Угадайте, к какому конструктору он обратится. И да, если мы скомпилируем этот код, он выдаст ошибку, а почему? Потому что мы ограничили видимость конструктора (видны только конструкторы с модификатором protected, public). Если вы удалите creatorVisibility, то он заработает. Возникает вопрос. А что за @JsonProperty в конструкторе. Об этом думаю рассказать в следующей части статьи. P.S. Господа, очень бы хотелось получить хоть какой-то отклик о статье. Интересно, пользуется ли спросом эта тема и стоит ли продолжать, потому что тем очень много и все они очень интересные. Хотелось бы еще рассмотреть такие аннотации, как @JsonView, @JsonManagedReference, @JsonBackReference, @JsonUnwrapped и т.д. Спасибо :)
Комментарии (14)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Ra
Уровень 51
Student
19 июля 2023, 13:38
Зачем это в поиск попадает. Начал читать и тут всё внезапно кончилось)))
Soros
Уровень 39
1 апреля 2020, 07:28
Видимо было очень холодно, что спустя два года продолжения нет.
Egor Patrikeev Backend Developer в Opal technology
24 августа 2019, 19:09
Доходчиво и по сути!! Спасибо очень помог, 2 часа бился пока не надыбал эту статью!
21 июля 2019, 13:58
Очень полезно и интересно - будем благодарны за продолжение.
Jors
Уровень 1
21 июня 2019, 05:31
А мне понравилось объяснение которое я посмотрел на ютюбе Изучение Jackson
Роман И Backend Developer в СберТех
26 апреля 2019, 16:01
Да, вот возникла потребность разобраться. Надо было сохранить переименованное поле для совместимости со старыми версиями клиентов.
Арман Матаков
Уровень 39
4 апреля 2019, 11:39
Было бы здорово если бы было еще, но как то более развернуто, с пояснениями, что куда и как работает.
rmuskovets
Уровень 41
7 ноября 2018, 17:45
помогло мне, а то забыл всё
Ярослав Java Developer Master
15 июня 2018, 17:05
Спасибо за статью, поставили кое-какие вещи на свои места в моей голове :)
Сергей Java Developer в Сбер Expert
24 мая 2018, 17:37
Не статья, а огрызок какой-то