SpringMVC的HTTP序列化和反序列化核心是HttpMessageConverter,在SSM项目中,我们需要在xml配置文件中注入MappingJackson2HttpMessageConverter。告诉SpringMVC我们需要JSON格式的转换。
在SpringMVC中配置消息转换器和三方消息转换器如代码1所示:
代码1:SpringMVC中配置MappingJackson2HttpMessageConverter
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
text/html;charset=UTF-8
我们使用的@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;
}
正常配置.png
由上图所示,返回参数通过@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对返回对象序列化的格式输出。
@ResponseBody特定的序列化格式.png
文章参考