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:
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:
@RestControllerpublic 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:
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:
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
:
@Configurationpublic 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:
- 👨💻 springboot and mvc
- 👨💻 Jackson tutorials
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!