Введение
В этой статье я научу вас, как использовать Jackson и Gson для сопоставления разных полей JSON с одним полем Java.
Зависимости 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.9.8</version>
<scope>test</scope>
</dependency>
Пример JSON
Предположим, мы хотим ввести информацию о погоде для разных мест в наш класс Java. Мы обнаружили несколько веб-сайтов, которые публикуют данные о погоде в виде документов JSON. Однако их формат не соответствует
{
"location": "广州",
"temp": 15,
"weather": "多云"
}
{
"place": "深圳",
"temperature": 35,
"outlook": "晴天"
}
Мы хотим десериализовать оба формата в один и тот же класс Java с именем Weather:
Используйте Джексона
Для этого мы будем использовать аннотации @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;
Getter、Setter忽略
Теперь, когда мы добавили аннотацию, давайте создадим объект Weather, используя метод ObjectMapper Джексона.
@Test
public void test() throws Exception {
ObjectMapper mapper = new ObjectMapper();
Weather weather = mapper.readValue("{\n"
+ " \"location\": \"广州\",\n"
+ " \"temp\": 15,\n"
+ " \"weather\": \"多云\"\n"
+ "}", Weather.class);
TestCase.assertEquals("广州", weather.getLocation());
TestCase.assertEquals("多云", weather.getOutlook());
TestCase.assertEquals(15, weather.getTemp());
weather = mapper.readValue("{\n"
+ " \"place\": \"深圳\",\n"
+ " \"temperature\": 35,\n"
+ " \"outlook\": \"晴天\"\n"
+ "}", Weather.class);
TestCase.assertEquals("深圳", weather.getLocation());
TestCase.assertEquals("晴天", weather.getOutlook());
TestCase.assertEquals(35, weather.getTemp());
}
Используйте Гсон
Теперь давайте посмотрим, как реализован Gson. Нам нужно использовать значение и альтернативный параметр в аннотации @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 test() throws Exception {
Gson gson = new GsonBuilder().create();
Weather weather = gson.fromJson("{\n"
+ " \"location\": \"广州\",\n"
+ " \"temp\": 15,\n"
+ " \"weather\": \"多云\"\n"
+ "}", Weather.class);
TestCase.assertEquals("广州", weather.getLocation());
TestCase.assertEquals("多云", weather.getOutlook());
TestCase.assertEquals(15, weather.getTemp());
weather = gson.fromJson("{\n"
+ " \"place\": \"深圳\",\n"
+ " \"temperature\": 35,\n"
+ " \"outlook\": \"晴天\"\n"
+ "}", Weather.class);
TestCase.assertEquals("深圳", weather.getLocation());
TestCase.assertEquals("晴天", weather.getOutlook());
TestCase.assertEquals(35, weather.getTemp());
}
в заключении
Мы видим это, используя альтернативные параметры @JsonAlias Джексона или Gson, мы можем легко преобразовать разные форматы JSON в один и тот же объект Java.