Jackson序列化(1)— [SpringBoot2.x]-Jackson在HttpMessageConverter(消息转换器)中的使用
Jackson序列化(2)— [SpringBoot2.x]-Spring容器中ObjectMapper配置
Jackson序列化(3)— Jackson中ObjectMapper配置详解
Jackson序列化(4)— Jackson“默认的”时间格式化类—StdDateFormat解析
Jackson序列化(5) — Jackson的ObjectMapper.DefaultTyping.NON_FINAL属性
Jackson序列化(6)— Java使用Jackson进行序列化
SpringMVC的HTTP序列化和反序列化核心是HttpMessageConverter
,在SSM项目中,我们需要在xml配置文件中注入MappingJackson2HttpMessageConverter
。告诉SpringMVC我们需要JSON格式的转换。
在SpringMVC中配置消息转换器和三方消息转换器如代码1所示:
代码1:SpringMVC中配置MappingJackson2HttpMessageConverter
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list >
<ref bean="mappingJacksonHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
我们使用的@RequestBody
和@ResponseBody
注解,他们的作用就是将报文反序列化/序列化POJO对象。在请求时SpringMVC
会在请求头中寻找contentType
参数,然后去匹配能够处理这种类型的消息转换器。而在返回数据时,SpringMVC
根据请求头的Accept
属性,再将对象转换成响应报文。
针对于JSON这个结构,Spring默认使用Jackson来进行序列化和反序列化。在SpringBoot中会将MappingJackson2HttpMessageConverter
自动装载到IOC容器中。
源码:org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
@Configuration
@ConditionalOnClass(ObjectMapper.class)
@ConditionalOnBean(ObjectMapper.class)
@ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY,
havingValue = "jackson", matchIfMissing = true)
protected static class MappingJackson2HttpMessageConverterConfiguration {
@Bean
@ConditionalOnMissingBean(value = MappingJackson2HttpMessageConverter.class,
ignoredType = { "org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter",
"org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" })
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}
而ObjectMapper
参数是Spring容器中的bean,当我们使用默认的配置对/testDate
进行http访问时。
测试代码
@RequestMapping("testDate")
@ResponseBody
public User getDateAndLocalDateTime(){
User user=new User();
user.setDate(new Date());
user.setLocalDateTime(LocalDateTime.now());
user.setUId("001");
return user;
}
/**
* 静态内部类,只在该类中使用
*/
@Data
static class User{
private String uId;
private Date date;
private LocalDateTime localDateTime;
}
由上图所示,返回参数通过@ResponseBody
注解进行了消息转换
最终转化为了JSON串。实际上是借助了MappingJackson2HttpMessageConverter
来完成的。
2. 自定义输出响应内容
MappingJackson2HttpMessageConverter
借助的是Jackson来完成序列化,那么若是可以修改Jackson
的配置,便可自定义输出响应内容。
对于Date或者LocalDateTime类型,我们希望按照yyyy-MM-dd HH:mm:ss
格式输出。
借着我们对ObjectMapper
进行功能加强(设置时间类序列化格式)。注意:该段代码并未覆盖SpringBoot自动装配的ObjectMapper
对象,而是加强其配置。详情请参考——SpringBoot2.x下的ObjectMapper配置原理
@Bean
public Jackson2ObjectMapperBuilderCustomizer customJackson() {
return jacksonObjectMapperBuilder -> {
//若POJO对象的属性值为null,序列化时不进行显示
jacksonObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
//针对于Date类型,文本格式化
jacksonObjectMapperBuilder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
//针对于JDK新时间类。序列化时带有T的问题,自定义格式化字符串
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
jacksonObjectMapperBuilder.modules(javaTimeModule);
};
}
再次请求,可以看到,得到的结果如下图所示。我们已经改变@ResponseBody对返回对象序列化的格式输出。