Сопоставьте несколько полей JSON с одним полем Java

Java

Введение

В этой статье я научу вас, как использовать 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.