Skip to content

How to do custom JSON serialization in SpringBoot(RESTful) apps

1. Introduction

This post demonstrates how to implement custom JSON serialization in SpringBoot applications (Spring MVC or RESTful services). By default, SpringBoot uses Jackson to serialize objects. For example:

If we have this object:

MyBean.java
public class MyBean {
private int id;
private String name;
private Date bornDate;
//getters and setters
...
}

And the above object is returned by a SpringBoot Restful service like this:

MyController.java
@RestController
public class MyController {
@RequestMapping(value="/myBean")
public @ResponseBody
MyBean myBean() {
MyBean result = new MyBean();
result.setId(1);
result.setName("Jackson");
result.setBornDate(new Date());
return result;
}
}

We run the SpringBoot app and visit http://localhost:8080/myBean, then we would get this result:

{"id":1,"name":"Jackson","bornDate":1561531639483}

The bornDate field is a Long literal. What if we want it to be in the format MM-dd-yyyy HH:mm:ss, like this:

{"id":1,"name":"Jackson","bornDate":"06-26-2019 06:47:19"}

How can we achieve this?

2. Environments

  • SpringBoot 1.x and 2.x

3. Ways to resolve this issue

3.1 Use @JsonFormat

You can use the @JsonFormat annotation to specify the pattern of the field for custom serialization, as shown below:

MyBean.java
public class MyBean {
private int id;
private String name;
@JsonFormat(pattern = "MM-dd-yyyy HH:mm:ss")
private Date bornDate;
//getters and setters
...
}

3.2 Use Custom JsonSerializer

The @JsonFormat annotation only changes the field it annotates. If you want to permanently change the serialization of a specific type, you can define a custom JsonSerializer.

First, define a custom JsonSerializer by extending the JsonSerializer class:

CustomDateSerializer.java
public class CustomDateSerializer extends JsonSerializer<Date> {
private static SimpleDateFormat formatter
= new SimpleDateFormat("MM-dd-yyyy hh:mm:ss");
@Override
public void serialize(Date date, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(formatter.format(date));
}
}

Then, add this custom serializer to the ObjectMapper:

JacksonConfig.java
@Configuration
public class JacksonConfig {
@Bean
@Primary
public ObjectMapper serializingObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(Date.class, new CustomDateSerializer()); //change all Date object's json serialization
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}

4. The @JsonSerialize(using = CustomDateSerializer.class) Problem

If we use the @JsonSerialize(using = CustomDateSerializer.class) annotation, we would get this error:

{"Map":{"timestamp":1561369998555,"status":500,"error":"Internal Server Error","message":"No converter found for return value of type: class com.bswen.sbmvc.domain.MyBean","path":"/myBean"}}%

It seems that this annotation is no longer supported by SpringBoot, so be cautious when using it.

5. Summary

This post demonstrated two approaches to implement custom JSON serialization in SpringBoot applications: using @JsonFormat for field-level customization and creating a custom JsonSerializer for type-level changes. The example source code is available on GitHub.

Custom JSON serialization is essential for tailoring API responses to specific requirements. By following the methods outlined above, you can ensure your SpringBoot applications serialize data exactly as needed.

Final Words + More Resources

My intention with this article was to help others who might be considering solving such a problem. So I hope that’s been the case here. If you still have any questions, don’t hesitate to ask me by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!