springboot-How to do custom JSON serialization in SpringBoot(RESTful) apps
1. Introduction
This post would demo how to do custom JSON serialization in SpringBoot apps(Spring MVC or RESTful service). 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:
@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 format MM-dd-yyyy HH:mm:ss,just like this:
{"id":1,"name":"Jackson","bornDate":"06-26-2019 06:47:19"}
How to do this job?
2. Environments
- SpringBoot 1.x and 2.x
3. Ways to do this job
3.1 use @JsonFormat
You can just use the @JsonFormat to specify the pattern of the field to do custom serialization, just as follows:
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 can only change the field with this annotation, if you want to permernantly change the serialization of some type, you can just define a custom JsonSerializer.
First define a custom JsonSerializer by extending the JsonSerializer:
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 ObjectMapper:
@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), 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 not supported by SpringBoot anymore, just be careful.
5. Summary
The example source code has been uploaded to github, you can visit here to view the example source codes.