In this post, we will compare the Gson and Jackson APIs for serializing and deserializing JSON data to Java objects and vice-versa.
Gson Maven dependency — latest version can be found here
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
Serialization with Gson
public class Employe {
private String firstName;
private String lastName;
private int age;
private BigDecimal salary;
private List<String> skills;
//getters and setters
}
Gson Serialization
//Skills
List<String> skills = new LinkedList<String>();
skills.add("Database");
skills.add("J2EE Programming");
skills.add("RestFul");
//Employe
Employe emp = new Employe();
emp.setFirstName("David");
emp.setLastName("Peter");
emp.setAge(33);
emp.setSalary(new BigDecimal("110000"));
emp.setSkills(skills);
//Serialization - conversion to json string
Gson gson = new Gson();
String serializedEmployee = gson.toJson(emp);
System.out.println(serializedEmployee);
Sample output:
{
"firstName":"David",
"lastName":"Peter",
"age":33,
"salary":110000,
"skills":[
"Database",
"RestFul",
"J2EE Programming"
]
}
Gson Deserialization
//from the above code deserialize
Employee emp2 = gson.fromJson(serializedEmployee, Employe.class)
If you compare both emp and emp2 they both are identical
Jackson Maven Dependency
You can get the latest version of Jackson here
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
Jackson Serialization
public class User {
public int id;
public String name;
}
public class Item {
public int id;
public String itemName;
public User owner;
}
Now, let’s serialize an Item entity with a User entity:
Item myItem = new Item(1, "iPhone", new User(2, "AppleUser"));
String serialized = new ObjectMapper().writeValueAsString(myItem);
The output looks like this:
{
"id": 1,
"itemName": "iPhone",
"owner": {
"id": 2,
"name": "AppleUser"
}
}
Custom Serializer on the ObjectMapper
import java.time.LocalDateTime;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
@Provider
public class JacksonConfig implements ContextResolver<ObjectMapper> {
private final ObjectMapper objectMapper;
public JacksonConfig() {
objectMapper = new ObjectMapper();
SimpleModule s = new SimpleModule();
s.addSerializer(Timestamp.class, new TimestampSerializerTypeHandler());
s.addDeserializer(Timestamp.class, new TimestampDeserializerTypeHandler());
objectMapper.registerModule(s);
};
@Override
public ObjectMapper getContext(Class<?> type) {
return objectMapper;
}
}
where the serializer should be something like this:
import java.io.IOException;
import java.sql.Timestamp;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class TimestampSerializerTypeHandler extends JsonSerializer<Timestamp> {
@Override
public void serialize(Timestamp value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
String stringValue = value.toString();
if(stringValue != null && !stringValue.isEmpty() && !stringValue.equals("null")) {
jgen.writeString(stringValue);
} else {
jgen.writeNull();
}
}
@Override
public Class<Timestamp> handledType() {
return Timestamp.class;
}
}
and deserializer something like this:
import java.io.IOException;
import java.sql.Timestamp;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class TimestampDeserializerTypeHandler extends JsonDeserializer<Timestamp> {
@Override
public Timestamp deserialize(JsonParser jp, DeserializationContext ds) throws IOException, JsonProcessingException {
SqlTimestampConverter s = new SqlTimestampConverter();
String value = jp.getValueAsString();
if(value != null && !value.isEmpty() && !value.equals("null"))
return (Timestamp) s.convert(Timestamp.class, value);
return null;
}
@Override
public Class<Timestamp> handledType() {
return Timestamp.class;
}
}