1. Обзор
В этом руководстве мы увидим, как использовать Jackson и Gson для сопоставления разных полей JSON с одним полем Java.
2. Зависимости Maven
Чтобы использовать библиотеки Jackson и Gson , нам нужно добавить следующие зависимости в наш POM:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
<scope>test</scope>
</dependency>
3. Пример JSON
Давайте представим, что мы хотим получить информацию о погоде для разных мест в наше Java-приложение. Мы нашли несколько веб-сайтов, которые публикуют данные о погоде в виде документов JSON. Однако они используют немного разные форматы:
{
"location": "London",
"temp": 15,
"weather": "Cloudy"
}
А также:
{
"place": "Lisbon",
"temperature": 35,
"outlook": "Sunny"
}
Мы хотим десериализовать оба этих формата в один и тот же класс Java с именем Weather
:
public class Weather {
private String location;
private int temp;
private String outlook;
}
Итак, давайте посмотрим, как мы можем добиться этого, используя библиотеки Jackson и Gson.
4. Использование Джексона
Для этого мы будем использовать аннотации @JsonProperty
и @JsonAlias Джексона
. Это позволит нам сопоставить более одного свойства JSON с одним и тем же полем Java .
Во-первых, мы собираемся использовать аннотацию @JsonProperty
, чтобы Джексон знал имя поля JSON для сопоставления. Значение в аннотации @JsonProperty
используется как для десериализации, так и для сериализации.
Затем мы можем использовать аннотацию @JsonAlias
. В результате Джексон узнает имена других полей в документе JSON, которые сопоставляются с полем Java. Значение в аннотации @JsonAlias
используется только для десериализации:
@JsonProperty("location")
@JsonAlias("place")
private String location;
@JsonProperty("temp")
@JsonAlias("temperature")
private int temp;
@JsonProperty("outlook")
@JsonAlias("weather")
private String outlook;
Теперь, когда мы добавили аннотации, давайте воспользуемся ObjectMapper
Джексона для создания объектов Java с помощью класса Weather :
@Test
public void givenTwoJsonFormats_whenDeserialized_thenWeatherObjectsCreated() throws Exception {
ObjectMapper mapper = new ObjectMapper();
Weather weather = mapper.readValue("{\n"
+ " \"location\": \"London\",\n"
+ " \"temp\": 15,\n"
+ " \"weather\": \"Cloudy\"\n"
+ "}", Weather.class);
assertEquals("London", weather.getLocation());
assertEquals("Cloudy", weather.getOutlook());
assertEquals(15, weather.getTemp());
weather = mapper.readValue("{\n"
+ " \"place\": \"Lisbon\",\n"
+ " \"temperature\": 35,\n"
+ " \"outlook\": \"Sunny\"\n"
+ "}", Weather.class);
assertEquals("Lisbon", weather.getLocation());
assertEquals("Sunny", weather.getOutlook());
assertEquals(35, weather.getTemp());
}
5. Использование Гсона
Теперь давайте попробуем то же самое с Гсоном. Нам нужно будет использовать значение
и альтернативные
параметры в аннотации @SerializedName
.
Первый будет использоваться по умолчанию, а второй будет использоваться для указания альтернативного имени поля JSON, которое мы хотим отобразить:
@SerializedName(value="location", alternate="place")
private String location;
@SerializedName(value="temp", alternate="temperature")
private int temp;
@SerializedName(value="outlook", alternate="weather")
private String outlook;
Теперь, когда мы добавили аннотации, давайте проверим наш пример:
@Test
public void givenTwoJsonFormats_whenDeserialized_thenWeatherObjectsCreated() throws Exception {
Gson gson = new GsonBuilder().create();
Weather weather = gson.fromJson("{\n"
+ " \"location\": \"London\",\n"
+ " \"temp\": 15,\n"
+ " \"weather\": \"Cloudy\"\n"
+ "}", Weather.class);
assertEquals("London", weather.getLocation());
assertEquals("Cloudy", weather.getOutlook());
assertEquals(15, weather.getTemp());
weather = gson.fromJson("{\n"
+ " \"place\": \"Lisbon\",\n"
+ " \"temperature\": 35,\n"
+ " \"outlook\": \"Sunny\"\n"
+ "}", Weather.class);
assertEquals("Lisbon", weather.getLocation());
assertEquals("Sunny", weather.getOutlook());
assertEquals(35, weather.getTemp());
}
6. Заключение
Мы увидели, что с помощью параметра Джексона @JsonAlias
или альтернативного
параметра Gson мы можем легко преобразовывать различные форматы JSON в один и тот же объект Java.
Вы найдете примеры в проектах Джексона и Гсона на GitHub .