Перейти к основному содержимому

Десериализовать случай со змеей в случай с верблюдом с Джексоном

· 3 мин. чтения

1. Обзор

Имена полей в объектах JSON могут быть в различных форматах. Когда мы хотим загрузить их в наши POJO, мы можем столкнуться с проблемой, когда имена свойств в нашем коде Java не соответствуют соглашению об именах в JSON.

В этом кратком руководстве мы увидим, как десериализовать поля JSON case змеи в поля case верблюда с помощью Jackson .

2. Установите Джексона

Начнем с добавления зависимости Jackson в наш файл pom.xml :

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13</version>
</dependency>

3. Десериализация со значениями по умолчанию

Рассмотрим пример класса User :

public class User {
private String firstName;
private String lastName;

// standard getters and setters
}

Давайте попробуем загрузить этот JSON, который использует стандарт именования Snake Case (имена в нижнем регистре, разделенные _ ):

{
"first_name": "Jackie",
"last_name": "Chan"
}

Во-первых, нам нужно использовать ObjectMapper для десериализации этого JSON:

ObjectMapper objectMapper = new ObjectMapper();
User user = objectMapper.readValue(JSON, User.class);

Однако, когда мы пытаемся это сделать, мы получаем ошибку:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "first_name" (class com.foreach.jackson.snakecase.User), not marked as ignorable (2 known properties: "lastName", "firstName"])

К сожалению, Джексон не может точно сопоставить имена в JSON с именами полей в User.

Далее мы узнаем три способа решения этой проблемы.

4. Используйте аннотацию @JsonProperty

Мы можем использовать аннотацию @JsonProperty для полей нашего класса, чтобы сопоставить поля с точными именами в нашем JSON:

public class UserWithPropertyNames {
@JsonProperty("first_name")
private String firstName;

@JsonProperty("last_name")
private String lastName;

// standard getters and setters
}

Теперь мы можем десериализовать наш JSON в UserWithPropertyNames :

ObjectMapper objectMapper = new ObjectMapper();
UserWithPropertyNames user = objectMapper.readValue(JSON, UserWithPropertyNames.class);
assertEquals("Jackie", user.getFirstName());
assertEquals("Chan", user.getLastName());

5. Используйте аннотацию @JsonNaming

Затем мы можем использовать аннотацию @JsonNaming для класса, и все поля будут десериализованы с использованием змеиного регистра :

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class UserWithSnakeStrategy {
private String firstName;
private String lastName;

// standard getters and setters
}

Затем снова десериализуйте наш JSON:

ObjectMapper objectMapper = new ObjectMapper();
UserWithSnakeStrategy user = objectMapper.readValue(JSON, UserWithSnakeStrategy.class);
assertEquals("Jackie", user.getFirstName());
assertEquals("Chan", user.getLastName());

6. Настройте ObjectMapper

Наконец, мы можем использовать метод setPropertyNamingStrategy в ObjectMapper , чтобы настроить его для всей сериализации:

ObjectMapper objectMapper = new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
User user = objectMapper.readValue(JSON, User.class);
assertEquals("Jackie", user.getFirstName());
assertEquals("Chan", user.getLastName());

Как мы видим, теперь мы можем десериализовать наш JSON в исходный объект User , даже несмотря на то, что класс User не имеет никакой аннотации.

Следует отметить, что существуют и другие соглашения об именах (например, случай кебаба), и приведенные выше решения также работают с ними.

7. Заключение

В этой статье мы рассмотрели различные способы десериализации полей JSON для случая змеи в поля для случая верблюда с помощью Jackson .

Во-первых, мы явно назвали поля. Затем мы устанавливаем стратегию именования для самого POJO.

Наконец, мы добавили глобальную конфигурацию в ObjectMapper .

Как всегда, пример кода из этой статьи можно найти на GitHub .