- Given a user defined object or POJO having null fields (i.e. some fields are null).
- When we are serializing object the null values gets serialized.
- Moreover, suppose object contains the date field also, then date field will be serialized as timestamp value.
- We will use ObjectMapper (jackson feature) to customize the serialization process.
In this post we will discuss about following:
- Object having null field are serialized as null (default behavior).
- We will customize the serialization, wherein null values would not be serialized
- Date field is serialized as time stamp (default behavior).
- We will serialized the date as standard date format (and not as timestamp).
1. Example – Default serialization of object (Object to JSON)
- Suppose, we have EmployeeModel class having date field and some uninitialized fields.
- Null fields are serialized in default object to json conversion.
EmployeeModel Class:
- The parameterized constructor is not setting lastName and contact.
- lastName and contact data members should be serialized as null.
package org.learn;
import java.util.Date;
public class EmployeeModel {
public String firstName;
public String lastName;
public String contact;
public int salary;
public Date dob;
public EmployeeModel() {} // JAXB needs this
public EmployeeModel(String firstName, int salary, Date dob) {
this.firstName = firstName;
this.salary = salary;
this.dob = dob;
}
}
Default json serialized for EmployeeModel
{
firstName: "Random Name 1b09",
lastName: null,
contact: null,
salary: 8240,
dob: 1457589257128
}
2. Customize Object to JSON serialization (objectmapper contextresolver)
We have used ObjectMapper (jackson) to customize the serialization process. ObjectMapperContextResolver class (Custom Serialization using ObjectMapper and ContextResolver)
- We will configure the objectMapper, date will not be serialize as timestamp (Date will be serialized in ISO format)
- We will set inclusion strategy, so that null fields will not be serialized.
package org.learn;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@Provider
public class ObjectMapperContextResolver implements ContextResolver {
private final ObjectMapper objectMapper = new ObjectMapper();
public ObjectMapperContextResolver() {
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setSerializationInclusion(Include.NON_NULL);
}
@Override
public ObjectMapper getContext(Class<?> type) { return objectMapper; }
}
3. RESTful Resource: Service class exposing rest interfaces using Jersey.
- Resource /json will produce the EmployeeModel class as JSON
- The generated JSON will have non fields and date field in standard format.
- Resource /xml will produce the EmployeeModel class as XML
- The output will be similar to JSON.
package org.learn;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/service")
public class Service {
private static final String text = "status :Server is running " + "\ntime : %s";
@GET
@Consumes(MediaType.TEXT_PLAIN)
public Response getText() {
String response = String.format(text, new Date());
return Response.status(Response.Status.OK)
.entity(response)
.type(MediaType.TEXT_PLAIN).build();
}
@GET
@Path("/json")
@Produces(MediaType.APPLICATION_JSON)
public EmployeeModel getJson() {
// ...........db operation..
// suppose we get these value from database
// ............
String randomName = "Random Name " + UUID.randomUUID().toString().substring(0, 4);
int randomSalary = new Random().nextInt((10000-6000) + 1) + 6000;
// returns the value received from database
return new EmployeeModel(randomName, randomSalary, new Date());
}
@GET
@Path("/xml")
@Produces(MediaType.APPLICATION_XML)
public EmployeeModel getXml() {
// ...........db operation..
// suppose we get these value from database
// ............
String randomName = "Random Name " + UUID.randomUUID().toString().substring(0, 4);
int randomSalary = new Random().nextInt((10000-6000) + 1) + 6000;
// returns the value received from database
return new EmployeeModel(randomName, randomSalary, new Date());
}
}
4. Maven dependencies of Jersey (POM file):
<properties>
<jdk_version>1.8</jdk_version>
<jersey_version>2.22.1</jersey_version>
<servlet_api_version>3.0.1</servlet_api_version>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey_version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey_version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey_version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet_api_version}</version>
</dependency>
</dependencies>
5. Web.xml: Filter configurations defined in web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>REST Web Application using Jersey Web Application</display-name>
<servlet>
<servlet-name>rest-server</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>org.learn</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest-server</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
6. Output: GET /json having non nulls & date field
{
firstName: "Random Name 7ea8",
salary: 8297,
dob: "2016-03-10T14:43:48.202+0000"
}
7. Output – GET /xml having non nulls & date field
<Employee> <firstName>Random Name 72f8</firstName> <salary>9122</salary> <dob>2016-03-10T20:15:48.865+05:30</dob> </Employee>
Download Code – Jersey ObjectMapper Serialize NonNull & Date