一、认识HttpMessageConverter
HttpMessageConverter(消息转换工具):
所有的JSON生成都离不开它,SpringMVC自动配置了Jackson
和Gson
的HttpMessageConverter
,因此用户使用Jackson
和Gson
的话吗,没有额外配置,只需要添加依赖即可。
Spring MVC使用HttpMessageConverter
接口转换HTTP请求和响应。明智的默认设置包含在开箱即用
中。意思是,如果你配置了Jackson
和Gson
,那么系统默认用你的,如果你没配置,则使用系统提供的!这也是Spring的主流思想:SpringBoot约定大于配置
1.API 返回结果又如何将 Java 对象解析成 json 格式数据返回给前端,即将服务端返回的对象序列化成JSON字符
2.前端传入的 json 数据如何被解析成 Java 对象作为 API入参,即将前端传来的JSON字符串反序列化成Java对象
二、查看源码
新建一个最简单的Spring项目,导入Web依赖,可以发现依赖里面包含了json依赖,因此无需另外加入任何依赖。
- json:
位置:org/springframework/boot/autoconfigure/http/JacksonHttpMessageConvertersConfiguration.java
(对于Gson是完全一致的,但是对Gson的使用,需要添加相应的Gson依赖;)
@Configuration(proxyBeanMethods = false)
class JacksonHttpMessageConvertersConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ObjectMapper.class)
@ConditionalOnBean(ObjectMapper.class)
@ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY,
havingValue = "jackson", matchIfMissing = true)
static class MappingJackson2HttpMessageConverterConfiguration {
@Bean
@ConditionalOnMissingBean(value = MappingJackson2HttpMessageConverter.class,
ignoredType = {
"org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter",
"org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" })
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}
@ConditionalOnClass(ObjectMapper.class)
:如果用户导入json依赖,系统才会默认使用以上配置,使用MappingJackson2HttpMessageConverter
转换工具类,才会生效。
@ConditionalOnMissingBean
:如果没有配置Bean,系统会默认使用这里的Bean,如果用户对时间格式等另外有需求,需要自主配置,系统则会优先使用用户配置的Bean而忽略系统配置的Bean
三、自定义配置
写一个简单的Controller类,进行简单的测试
@RestController
@RequestMapping("/test")
public class StudentController {
@GetMapping("/hello")
public Student get(){
Student student = new Student();
student.setId((long) 1);
student.setAge(15);
student.setName("alvin");
student.setBirthday(new Date());
return student;
}
}
Postman调用接口
在实体类相应的映射字段加上 @JsonFormat(pattern = "yyyy-MM-dd")
注解,进行格式修改
public class Student {
private Long id;
private String name;
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthday
}
这种方式操作简单,但是实用性不是很强,如果项目中包含多个实体类,而且每个实体类含有多个Date属性,采用这种方式一个一个添加会非常的繁琐而且容易出错!
因此,使用全局配置更为方便,就是利用JacksonHttpMessageConvertersConfiguration.java
的作用,用户可以自主配置相应的json转换格式
配置方法:
方案一:
新建一个JsonConfig.java
作为配置类(测试之前记得把 @JsonFormat(pattern = "yyyy-MM-dd")
注解注释掉)
@Configuration
public class JsonConfig {
@Bean
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
//更改日期全局配置
objectMapper.setDateFormat(new SimpleDateFormat("yyyy/MM/dd"));
converter.setObjectMapper(objectMapper);
return converter;
}
}
该Bean将会取代JacksonHttpMessageConvertersConfiguration.java
的bean,因为@ConditionalOnMissingBean
已经不满足了,系统默认的配置自动失效。
- postman调用,日期格式已生成
objecMapper下面的其他的很多配置也可以通过这种方式使用:
方案二:
通过方案一可以发现,修改格式的操作主要是对objecMapper
进行操作的,MappingJackson2HttpMessageConverter
仅仅是提供一个对象,实际上并没有对我们的格式操作做任何事情,所以我们可以单独提供ObjectMapper
在JacksonHttpMessageConvertersConfiguration.java中出现@ConditionalOnClass(ObjectMapper.class),其中的Objectmapper是从另外一个配置注入进来的,即JacksonAutoConfiguration.java
位置:org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java
当然,我们在此处debug一下进行验证,确实程序经过了此处!
因此,我们可以单独在JsonConfig.java
配置ObjectMapper即可!
@Bean
ObjectMapper objectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat("yyyy/MM/dd"));
return objectMapper;
}
Debug一下,发现程序走了用户自主配置的@Bean,而自动忽略了系统自动配置的@Bean
仍然是生效的: