共计 2686 个字符,预计需要花费 7 分钟才能阅读完成。
简介
本文中,教大家如何使用 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:
使用 Jackson
为实现这一目标,我们将使用 Jackson 的 @JsonProperty 和 @JsonAlias 注释。这两个注解将帮助我们把 JSON 属性映射到同一 Java 字段。
首先,我们将使用 @JsonProperty 注释,以便让 Jackson 知道要映射的 JSON 字段的名称。在值 @JsonProperty 注解同时用于反序列化和序列化。
然后我们可以使用 @JsonAlias 注释。因此,Jackson 将知道 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 忽略
现在我们已经添加了注释,让我们使用 Jackson 的 ObjectMapper 方法创建 Weather 对象。
@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
现在,我们来看看 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());
}
结论
我们通过使用 Jackson 的 @JsonAlias 或 Gson 的替代参数看到了这一点,我们可以轻松地将不同的 JSON 格式转换为相同的 Java 对象。