Spring boot json序列化的配置

先贴配置

这段配置配置了Long类型和时间类型的序列化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

/**
* 自定义json序列化
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder ->
builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss")
// long类型转string, 前端处理Long类型,数值过大会丢失精度
.serializerByType(Long.class, ToStringSerializer.instance)
.serializerByType(Long.TYPE, ToStringSerializer.instance)
.serializationInclusion(JsonInclude.Include.NON_NULL)
//指定反序列化类型,也可以使用@JsonFormat(pattern = "yyyy-MM-dd")替代。主要是mvc接收日期时使用
.deserializerByType(LocalTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")))
.deserializerByType(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
// 日期序列化,主要返回数据时使用
.serializerByType(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")))
.serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}

集成原理

Spring boot通过JacksonAutoConfiguration类来实现jackson的个性化的配置

在这个类中有如下代码:

1
2
3
4
5
6
@Bean
@Primary
@ConditionalOnMissingBean
ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.createXmlMapper(false).build();
}

这段代码注册了一个ObjectMapper的bean(ObjectMapper用于java对象的序列化和反序列化),需要完成这个bean的创建,需要提供Jackson2ObjectMapperBuilderd的bean

在这个类中,还可以找到如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
static class JacksonObjectMapperBuilderConfiguration {

@Bean
@Scope("prototype")
@ConditionalOnMissingBean
Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(ApplicationContext applicationContext,
List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.applicationContext(applicationContext);
customize(builder, customizers);
return builder;
}

private void customize(Jackson2ObjectMapperBuilder builder,
List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
for (Jackson2ObjectMapperBuilderCustomizer customizer : customizers) {
customizer.customize(builder);
}
}

}

此段代码会生成一个Jackson2ObjectMapperBuilder的bean,也就是我们上面生成ObjectMapper使用到的bean,而Jackson2ObjectMapperBuilder bean的生成又依赖了List

等于说spring boot会把容器里面的所有的Jackson2ObjectMapperBuilderCustomizer拿出来,统一对Jackson2ObjectMapperBuilder进行设置操作,也就间接的控制了ObjectMapper的生成,所以我们如果要对ObjectMapper做特殊的配置化操作的话,我们只需要实现Jackson2ObjectMapperBuilderCustomizer这个接口并注册这个实现的bean就可以了。可以看到Jackson2ObjectMapperBuilderCustomizer只有一个方法,void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder);其实就是Jackson2ObjectMapperBuilder提供给用户的回调钩子方法,我们只需要使用Jackson2ObjectMapperBuilder进行配置就可以了。