1. 概述
在本教程中,我們將學習如何使用 Jackson 和 Gson 將不同的 JSON 字段映射到單個 Java 字段。
2. Maven 依賴
為了使用 Jackson 和 Gson 庫,我們需要將以下依賴項添加到我們的 POM 中:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</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"
}And:
{
"place": "Lisbon",
"temperature": 35,
"outlook": "Sunny"
}我們希望將這兩種格式都反序列化到同一個 Java 類中,該類名為 Weather:
public class Weather {
private String location;
private int temp;
private String outlook;
}讓我們看看如何使用 Jackson 和 Gson 庫來實現這一點。
4. 使用 Jackson
為了實現這一點,我們將利用 Jackson 的 <em @JsonProperty</em> 和 <em @JsonAlias</em> 註解。這些註解將允許我們將多個 JSON 屬性映射到同一個 Java 字段上。
首先,我們將使用 <em @JsonProperty</em> 註解,以便 Jackson 知道要映射的 JSON 字段的名稱。<em @JsonProperty</em> 註解中的值用於序列化和反序列化。
然後,我們可以使用 <em @JsonAlias</em> 註解。 這樣,Jackson 將知道 JSON 文檔中其他映射到 Java 字段的字段名稱。 <em @JsonAlias</em> 註解中的值僅用於反序列化。
@JsonProperty("location")
@JsonAlias("place")
private String location;
@JsonProperty("temp")
@JsonAlias("temperature")
private int temp;
@JsonProperty("outlook")
@JsonAlias("weather")
private String outlook;
現在我們已經添加了註釋,接下來我們將使用 Jackson 的 ObjectMapper 來使用 Weather 類創建 Java 對象:
@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. 使用 Gson
現在,我們嘗試使用 Gson 實現同樣的功能。我們需要在 value 和 alternate 參數中利用 註解。
其中一個參數將作為默認值使用,另一個參數將用於指示我們希望映射的 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. 結論
我們看到,無論使用 Jackson 的 <em >@JsonAlias</em> 還是 Gson 的 <em >alternate</em> 參數,我們都可以輕鬆地將不同的 JSON 格式轉換為相同的 Java 對象。