- 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