RESTFul web service serialize non null & date field (jersey /objectmapper /contextresolver)

  • 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:

  1. Object having null field are serialized as null (default behavior).
    • We will customize the serialization, wherein null values would not be serialized
  2. 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

 

Scroll to Top