Jackson – это мощная библиотека для обработки JSON. Это библиотека по умолчанию, используемая платформой Spring. Он очень гибкий и настраиваемый. Стандартный способ его настройки – использование аннотаций в обрабатываемых классах.
В этом посте я объясню, как использовать библиотеку Moonwalker , которую я создал. Это фасад для Джексона и предоставляет API-интерфейс разработчика для настройки Джексона. Таким образом, вы можете избавиться от аннотаций в своих классах. Я также покажу вам, как интегрировать Moonwalker в приложения Spring Boot.
Прежде чем мы погрузимся в примеры кода, почему вы хотите избавиться от аннотаций в своих классах? Причин может быть несколько, в том числе:
- Аннотации относятся к JSON, и вы не хотите привязывать себя к использованию JSON в качестве механизма сериализации.
- У вас нет доступа к некоторым классам, в которые вам нужно было бы поместить аннотации, например, суперклассы фреймворка.
- Вы следуете принципам проектирования, управляемого доменом (DDD), чтобы публиковать/подписываться на события домена, и не хотите, чтобы ваши классы событий домена были загромождены аннотациями, специфичными для технологии.
Давайте рассмотрим варианты использования и то, как Moonwalker может помочь в этом.
Допустим, у вас есть суперкласс Человек
, с подклассом Сотрудник
. Стандартный способ рассказать Джексону об отношениях наследования – использовать аннотации в суперклассе:
@JsonTypeInfo(property = "@type", include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.MINIMAL_CLASS) @JsonSubTypes({ @JsonSubTypes.Type(value = Employee.class) }) public class Person { private String firstName; private String lastName; public Person() { } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
Что означает свойство
в аннотации? Он объявляет, что JSON содержит свойство с именем @type
. Его значением является имя подкласса, чтобы Джексон знал, какой конкретный экземпляр класса создавать при десериализации. Как вы можете видеть, суперкласс должен содержать все подклассы, в данном случае класс Employee
. Вот код:
public class Employee extends Person{ private String employeeNumber; public Employee() { } public String getEmployeeNumber() { return employeeNumber; } public void setEmployeeNumber(String employeeNumber) { this.employeeNumber = employeeNumber; } }
Вот как вы десериализуете JSON в объект Employee
, учитывая, что класс Employee
находится в том же пакете, что и класс Person
.
ObjectMapper objectMapper = new ObjectMapper(); String jsonString = "{ \"@type\" : \".Employee\", \"firstName\" : \"Jane\", \"lastName\" : \"Doe\" , \"employeeNumber\" : \"EMP-2020\"}"; Employee employee = (Employee) objectMapper.readValue(jsonString, Person.class);
Как Лунатик справляется с наследованием
Когда вы используете Moonwalker, вы можете избавиться от всех аннотаций в суперклассе. Вместо этого вы создаете и регистрируете модуль, содержащий сопоставление между свойством JSON, например @тип
и суперкласс, например Человек
:
ObjectMapper objectMapper = new ObjectMapper(); MoonwlkerModule module = MoonwlkerModule.builder() .fromProperty("@type").toSubclassesOf(Person.class) .build(); objectMapper.registerModule(module);
JSON выглядит почти идентично, за исключением того, что перед именем класса в свойстве @type
нет начальной точки:
String jsonString = "{ \"@type\" : \"Employee\", \"firstName\" : \"Jane\", \"lastName\" : \"Doe\" , \"employeeNumber\" : \"EMP-2020\"}"; Employee employee = (Employee) objectMapper.readValue(jsonString, Person.class);
И это все.
Чтобы интегрировать Moonwalker в проект Spring Boot, все, что вам нужно сделать, это зарегистрировать компонент для ObjectMapper
:
@SpringBootApplication public class GreeterApplication { public static void main(String[] args) { SpringApplication.run(GreeterApplication.class, args); } @Bean ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); MoonwlkerModule module = MoonwlkerModule.builder() .fromProperty("@type").toSubclassesOf(Person.class) .build(); objectMapper.registerModule(module); return objectMapper; } }
Стандартным способом, которым Джексон поддерживает все конструкторы аргументов, является использование @JsonCreator
и @jsonproperties
аннотации. Moonwalker изменяет это: он позволяет десериализовать объекты, у которых есть один конструктор по умолчанию для всех аргументов.
Пример класса, который может быть (де)сериализован с помощью Moonwalker, может выглядеть следующим образом:
public class Dog extends Animal { private final String name; private final String command; public Dog(BigDecimal price, String name, String command) { super(price); this.name = name; this.command = command; } public String name() { return name; } public String command() { return command; } }
Подробнее о том, как включить эту функцию, смотрите на веб-сайте Moonwalker .
Проект “Лунный ходок” находится в стадии разработки. Любая обратная связь приветствуется. Оставьте заметку в комментариях. Или станьте участником. Спасибо!
Оригинал: “https://dev.to/bertilmuth/moonwlker-json-without-annotation-1692”