Custom Jackson Joda DateTime Serializer

This tutorial shows how to serialize date format when marshaling JSON using Jackson. The custom annotation will be created in order to pass the date format using annotation.


Below is the pom.xml file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>roytuts</groupId>
	<artifactId>jackson</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>jackson</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<jdk.version>1.8</jdk.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.9.0.pr2</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.datatype</groupId>
			<artifactId>jackson-datatype-joda</artifactId>
			<version>2.9.0.pr2</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.0.pr2</version>
			<type>jar</type>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${jdk.version}</source>
					<target>${jdk.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Below custom annotation is used to annotate the date format.

package json;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyDateFormat {
	String value() default "dd/MM/yyyy";
}

The above annotation has default date format. So if you do not pass any date format while applying annotation then the default format will be applied.

Create below custom date serializer class in order to get the desired date or datetime format in JSON data.

package json;
import java.io.IOException;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
public class MyJsonDateTimeSerializer extends JsonSerializer<DateTime> implements ContextualSerializer {
	private String format;
	public MyJsonDateTimeSerializer() {
	}
	public MyJsonDateTimeSerializer(String format) {
		this.format = format;
	}
	@Override
	public void serialize(DateTime dt, JsonGenerator jg, SerializerProvider sp)
			throws IOException, JsonProcessingException {
		DateTimeFormatter formatter = DateTimeFormat.forPattern(format);
		jg.writeString(formatter.print(dt));
	}
	@Override
	public JsonSerializer<?> createContextual(SerializerProvider sp, BeanProperty bp) throws JsonMappingException {
		return new MyJsonDateTimeSerializer(bp.getAnnotation(MyDateFormat.class).value());
	}
}

In the above class joda DateTime api has been used. Also notice how annotated MyDateFormat class has been used to get the annotated value for formatting the date.

Now create below POJO class and apply the annotation on DateTime fields.

package json;
import org.joda.time.DateTime;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
public class MyPojo {
	private String name;
	@MyDateFormat("dd-MM-yyyy HH:mm:ss")
	@JsonSerialize(using = MyJsonDateTimeSerializer.class)
	private DateTime startDate;
	@MyDateFormat("dd-MM-yyyy")
	@JsonSerialize(using = MyJsonDateTimeSerializer.class)
	private DateTime endDate;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public DateTime getStartDate() {
		return startDate;
	}
	public void setStartDate(DateTime startDate) {
		this.startDate = startDate;
	}
	public DateTime getEndDate() {
		return endDate;
	}
	public void setEndDate(DateTime endDate) {
		this.endDate = endDate;
	}
	@Override
	public String toString() {
		return "MyPojo [name=" + name + ", startDate=" + startDate + ", endDate=" + endDate + "]";
	}
}

See how date format annotation has been used in the above class fields.
Create below test class in order to test the custom serializer

package json;
import java.io.IOException;
import org.joda.time.DateTime;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonDateTimeSerializerTest {
	public static void main(String[] args) throws IOException {
		// Serialize
		MyPojo mp = new MyPojo();
		mp.setName("POJO One");
		mp.setStartDate(new DateTime());
		mp.setEndDate(new DateTime());
		ObjectMapper mapper = new ObjectMapper();
		String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mp);
		System.out.println(json);
	}
}

Output

{
  "name" : "POJO One",
  "startDate" : "17-05-2017 08:36:11",
  "endDate" : "17-05-2017"
}

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *