1. Overview
In this tutorial, we’ll see how to use both Jackson and Gson to map different JSON fields onto a single Java field.
2. Maven Dependencies
In order to use the Jackson and Gson libraries we need to add the following dependencies to our 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>
3. Sample JSON
Let’s imagine that we want to get the details of the weather for different locations into our Java application. We’ve found a couple of web sites that publish weather data as JSON documents. However, they use slightly different formats:
{ "location": "London", "temp": 15, "weather": "Cloudy" }
And:
{ "place": "Lisbon", "temperature": 35, "outlook": "Sunny" }
We want to deserialize both of these formats into the same Java class, named Weather:
public class Weather { private String location; private int temp; private String outlook; }
So let’s take a look at how we can achieve this using both Jackson and Gson libraries.
4. Using Jackson
To achieve this, we’ll make use of Jackson’s @JsonProperty and @JsonAlias annotations. These will allow us to map more than one JSON property onto the same Java field.
First, we’re going to use the @JsonProperty annotation, so that Jackson knows the name of the JSON field to map. The value in the @JsonProperty annotation is used for both deserializing and serializing.
Then we can use the @JsonAlias annotation. As a result, Jackson will know the names of other fields in the JSON document that are mapped to the Java field. The value in the @JsonAlias annotation is only used for deserializing:
@JsonProperty("location") @JsonAlias("place") private String location; @JsonProperty("temp") @JsonAlias("temperature") private int temp; @JsonProperty("outlook") @JsonAlias("weather") private String outlook;
Now that we’ve added the annotations, let’s use Jackson’s ObjectMapper to create Java objects using the Weather class:
@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. Using Gson
Now, let’s try the same with Gson. We’ll need to use the value and the alternate parameters in the @SerializedName annotation.
The first one will be used as a default, while the second will be used to indicate an alternate name of the JSON field that we want to map:
@SerializedName(value="location", alternate="place") private String location; @SerializedName(value="temp", alternate="temperature") private int temp; @SerializedName(value="outlook", alternate="weather") private String outlook;
Now that we’ve added the annotations, let’s test our example:
@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. Conclusion
We saw that by using either Jackson’s @JsonAlias or Gson’s alternate parameter, we can easily convert different JSON formats into the same Java object.
You’ll find the examples in the Jackson and the Gson projects on GitHub.