SpringBoot如何配置全局JSON序列化、反序列化
Spring Boot如何配置全局JSON序列化、反序列化
起因
当我们在写web接⼝时,常以JSON格式返回,但是对于⼀些⽇期、枚举之类的处理通常需要
加@JsonFormat和@JsonValue、@JsonSerialize之类的注解进⾏特定的序列化处理。那么对于公⽤的序列化处理该如何实现呢?
知识储备
1. 了解@JsonFormat和@JsonValue、@JsonSerialize之类的注解,⽅便进⾏⽐较
2. 了解Jackson序列化
3. 了解@EnableWebMvc的作⽤,
四种全局序列化⽅式
Spring Boot默认采⽤Jackson进⾏序列化,所以提供的四种全局序列化⽅式都是针对于Jackson,对于fastJson⽅式下⽂中也会顺便提⼀下。本⽂以对枚举类的全局序列化来举例。
1.通过@JsonComponent(推荐)
⾸先话不多说先看个例⼦。
定义枚举类
public enum CurrCode implements BaseEnum {
RMB("156","rmb"),USD("840","usd");
private String code;
private String desc;
CurrCode(String code, String desc){
this.desc = desc;
}
@JsonCreator
public static CurrCode of(@JsonProperty("code") String c){
for(CurrCode value : CurrCode.values()){
Code().equals(c)){
return value;
}
}
return null;
}
public String getCode(){
return code;
}
public String getDesc(){
return desc;
}
@Override
public String toString(){
return"CurrCode{"+
"code='"+ code +'\''+
", desc='"+ desc +'\''+
'}';
}
@Override
public String getValue(){
return getCode();
}
}
定义配置类
@JsonComponent
public class JacksonComponent {
public static class CurrCodeJsonSerializer extends JsonSerializer<CurrCode>{
@Override
public void serialize(CurrCode currCode, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)throws IOException {
jsonGenerator.Code());
}
}
}
分析
查看@JsonComponent源码
@Component that provides JsonSerializer,JsonDeserializer or KeyDeserializer implementations to be registered with Jackson when JsonComponentModule is in use. Can be used to annotate implementations directly or a class that contains them as inner-classes.
翻译:@Component,提供JsonSerializer,JsonDeserializer或KeyDeserializer实现,以便在使⽤JsonComponentModule时向Jackson进⾏注册。可⽤于直接注解实现或包含它们作为内部类的类。
@JsonComponent
public class CustomerJsonComponent {
public static class Serializer extends JsonSerializer<Customer>{
// ...
}
public static class Deserializer extends JsonDeserializer<Customer>{
// ...
}
}
上⾯源码⾥给出的例⼦在@JsonComponent注解所修饰的类⾥⾯添加继承JsonSerializer的内部类,spring就会⾃动帮助我们将定义的序列化类注册到jackson⾥去。这个过程使⽤的仍然是Spring Boot⾃动配置web mvc,这样静态资源不会失效。推荐使⽤这种⽅式实现全局JSON序列化。
补充:@JsonComponent注解value⽤来指定注册到Spring容器⾥的Bean Name,type⽤来指定对哪些类进⾏了序列化或反序列化处
理。scope指定对在作⽤范围。
2.Jackson2ObjectMapperBuilderCustomizer
使⽤Jackson2ObjectMapperBuilderCustomizer实现全局序列化、反序列化,这个过程使⽤的仍然是Spring Boot⾃动配置web mvc,这样静态资源不会失效。
@Configuration
public class LocalDateTimeSerializerConfig {
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(){
return builder -> builder.serializerByType(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)));
}
}
3.ObjectMapper
使⽤ObjectMapper实现全局序列化、反序列化,这个过程使⽤的仍然是Spring Boot⾃动配置web mvc,这样静态资源不会失效。
@Configuration
public class LocalDateTimeSerializerConfig {
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
@Bean
public ObjectMapper customObjectMapper(){
JavaTimeModule javaTimeModule =new JavaTimeModule();
javaTimeModule.addSerializer(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)));
ObjectMapper objectMapper =new ObjectMapper();
return objectMapper;
}
}
springboot推荐算法4.WebMvcConfigurationSupport配置(了解)
@Configuration
public class JacksonConfig extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters){
MappingJackson2HttpMessageConverter converter =new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper =new ObjectMapper();
SimpleModule simpleModule =new SimpleModule();
simpleModule.addSerializer(CurrCode.class,new CurrCodeJsonSerializer());
// 配置null值序列化成空字符串
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)throws IOException {
jsonGenerator.writeString("");
}
});
//这⾥是fastJSON的配置⽅式,更多的内容可以查看SerializerFeature
// FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
// converter.setFeatures(SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero,
//        SerializerFeature.WriteNullBooleanAsFalse, SerializerFeature.WriteNullListAsEmpty);
converter.setObjectMapper(objectMapper);
converters.add(converter);
}
public static class CurrCodeJsonSerializer extends JsonSerializer<CurrCode>{
@Override
public void serialize(CurrCode currCode, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)throws IOException {
jsonGenerator.Code());
}
}
}
分析
继承WebMvcConfigurationSupport类主要是需要往web mvc配置中添加对于我们要特殊处理类的转换器(HttpMessageConverter的⼦类),由于我们使⽤的是Jackson序列化对象所以需要往转换⾥添加J
ackson提供的转换器即
MappingJackson2HttpMessageConverter。如果使⽤fastjson可以使⽤转换器FastJsonHttpMessageConverter。
补充:
1.WebMvcConfigurationSupport会屏蔽Spring Boot的⾃动配置。这样会导致⾃动配置的静态资源路径
(classpath:/META/resources/,classpath:/resources/,classpath:/static/,classpath:/public/)⽆法访问。
2.上⾯的配置类同样可以实现WebMvcConfigurer,实现同名的configureMessageConverters⽅法具体同上。但是需要这个配置类起作⽤需要在配置类上加上@EnableWebMvc注解。
3.@EnableWebMvc注解同样会导致⾃动配置的静态资源路径⽆法访问,也会导致@JsonFormat之类的注解⽆法⼯作。
测试
定义⼀个测试的接⼝如下
@RestController
public class JacksonController {
@GetMapping(path ="/test")
public Param getTest(){
Param param =new Param();
param.setCurrCode(CurrCode.RMB);
return param;
}
}
利⽤postman⼯具发送请求,查看返回结果,如下可以看出返回的是枚举类的code⽽不是枚举名称。
总结
以上四种⽅式都能实现全局JSON序列化,但是为了保证避免静态资源路径⽆法访问以及@JsonFormat之类的注解⽆法⼯作的问题,推荐使⽤第⼀种⽅法使⽤@JsonComponent注解来实现全局JSON序列化或者第⼆三两种⽅案都可。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。