Spring Boot对web层进行了一系列的自动化配置,只需要引入web依赖,零配置,就可以直接使用spring mvc 里面的东西,这篇看一下它对json的自动化配置:
创建一个web项目,勾选web的依赖,就可以看到依赖里面引入了json
在前后端分离的项目中,前后端的交互是通过json格式进行的。那么在Spring Boot中如何使用呢?
我们先看一个消息转化工具(HttpMessageConverter),所用的json生成都离不开它,它的作用:
1.将服务端返回的对象序列化成JSON字符串
2.将前端传来的JSON字符串反序列化成java对象
Spring MVC自动配置了Jackson和Gson的HttpMessageConverter,在Spring Boot中如果需要使用的话,只需要引入依赖就可以直接使用了。
我们看一下他的自动化配置的源码,双击shift,去搜JacksonHttpMessageConvertersConfiguration,里面有一个方法就是对json的转化,所以当引入依赖的时候,这个类才会生效,里面的方法才会执行。
//这个是用来处理json的配置类的源码 // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.boot.autoconfigure.http; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; @Configuration( proxyBeanMethods = false ) class JacksonHttpMessageConvertersConfiguration { JacksonHttpMessageConvertersConfiguration() { } @Configuration( proxyBeanMethods = false ) @ConditionalOnClass({XmlMapper.class}) @ConditionalOnBean({Jackson2ObjectMapperBuilder.class}) protected static class MappingJackson2XmlHttpMessageConverterConfiguration { protected MappingJackson2XmlHttpMessageConverterConfiguration() { } @Bean @ConditionalOnMissingBean public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter(Jackson2ObjectMapperBuilder builder) { return new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()); } } @Configuration( proxyBeanMethods = false ) @ConditionalOnClass({ObjectMapper.class}) @ConditionalOnBean({ObjectMapper.class}) @ConditionalOnProperty( name = {"spring.http.converters.preferred-json-mapper"}, havingValue = "jackson", matchIfMissing = true ) static class MappingJackson2HttpMessageConverterConfiguration { 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); } } }
说了这么多,感觉这个消息转化工具和我们没啥关系,只需要加入依赖就可以了,剩下的就不用管了。实则不然,Spring Boot的核心理念就是约定大于配置,当我们不配置的时候,就使用它默认的,但是当我们配置的时候,就使用我们的。当有特定的需求的时候,就需要进行配置,来满足我们的需要,举一个栗子,如果我们的json数据里面有日期格式的时候,我们通常需要对它进行格式化,通常的做法,就是在属性上边加上一个注解@JsonFormat(pattern=“yyyy-MM-dd”),但是如果我们有很多个日期的时候,就需要给每一个都加上,显然效率会降低,因此我们可以做一个全局配置,也就是对MappingJackson2HttpMessageConverter ,这个方法重新配置:
package com.config; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.text.SimpleDateFormat; //这是一个配置类,当这个bean注入进去的时候,源码中@ConditionalOnMissingBean/就会失效 @Configuration public class WebMvcConfig { @Bean MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){ MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper mapper = new ObjectMapper(); mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); mappingJackson2HttpMessageConverter.setObjectMapper(mapper); return mappingJackson2HttpMessageConverter ; } }
我们看一下运行结果:
日期格式格式化了,但是我们看这个配置,其实发挥作用的就是ObjectMapper ,因此我们也可以直接配置ObjectMapper 。这里我们可以看到ObjectMapper 在源码中是注入进去的,这里可以看一下另一个配置类,JacksonAutoConfiguration,json的自动化配置类
//这个是他定义的ObjectMapper ,也是注入到MappingJackson2HttpMessageConverter 里面的ObjectMapper
@Bean
@Primary
@ConditionalOnMissingBean
ObjectMapper jacksonObjectMapper(
Jackson2ObjectMapperBuilder builder)
{ return builder.createXmlMapper(false).build(); }
它生效的条件@ConditionalOnMissingBean ,如果没有配置就用它的,如果配置了,就用你的。我们看一下它如何配置:
package com.config; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.text.SimpleDateFormat; @Configuration public class WebMvcConfig { /*@Bean MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){ MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper mapper = new ObjectMapper(); mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); mappingJackson2HttpMessageConverter.setObjectMapper(mapper); return mappingJackson2HttpMessageConverter ; }*/ @Bean ObjectMapper objectMapper(){ ObjectMapper mapper = new ObjectMapper(); mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); return mapper; } }
好了,基本的原理就是这样,当然里面的配置还有很多,有兴趣的话,可以自己尝试,
下面我们看一下Gson
gson的话使用上和json一样,但是当加入web依赖的时候,默认会加入json的依赖,所以,要在pom里面剔除json依赖,加入gson的依赖,就可以使用了
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--排除json的依赖--> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency>
这样就可以直接使用了。
fastjson,Spring Boot 对它没有提供自动化配置,因此,我们要自已配置fastjson的消息转化工具,FastJsonHttpMessageConverter。
具体代码我上传到GitHub上,如果有兴趣可以克隆下来看看。
项目地址:https://github.com/buliangrengithub/Boot.git,有什么不懂得可以在GitHub上提问,也可以在博客上评论。