SpringBoot自定义HttpMessageConverter
我编写了一个Controller,返回User类型的数据,Spring会把User转化成JSON字符串,现在我想对这个字符串进行一些处理再返回。要求不能更改Controller部分的代码,因为我要对全部的返回的JSON都进行这种处理,如果改Controller的话需要更改好多地方。
@RestController class MyController { @RequestMapping("user") User getUser() { return new User("weidiao", 25); } }
虽然这个函数返回的User类型,实际上Spring会把这个对象转换成JSON。跟@ResponseBody
、@RequestBody
两个注解密切相关的一个接口是:HttpMessageConverter。
消息转换器的目标是:HTTP输入请求格式向Java对象的转换;Java对象向HTTP输出请求的转换。有的消息转换器只支持多个数据类型,有的只支持多个输出格式,还有的两者兼备。
HttpMessageConverter 接口提供了5个方法:
- canRead :判断该转换器是否能将请求内容转换成Java对象
- canWrite :判断该转换器是否可以将Java对象转换成返回内容
- getSupportedMediaTypes :获得该转换器支持的MediaType类型
- read :读取请求内容并转换成Java对象
- write :将Java对象转换后写入返回内容
其中 read 和 write 方法的参数分别有有 HttpInputMessage 和 HttpOutputMessage 对象,这两个对象分别代表着一次Http通讯中的请求和响应部分,可以通过 getBody 方法获得对应的输入流和输出流。
Spring已经默认包含了常用的消息转换器:
名称 | 作用 | 读支持MediaType | 写支持MediaType |
---|---|---|---|
ByteArrayHttpMessageConverter | 数据与字节数组的相互转换 | / | application/octet-stream |
StringHttpMessageConverter | 数据与String类型的相互转换 | text/* | text/plain |
FormHttpMessageConverter | 表单与MultiValueMap<string, string=””> 的相互转换 |
application/x-www-form-urlencoded | application/x-www-form-urlencoded |
SourceHttpMessageConverter | 数据与javax.xml.transform.Source的相互转换 | text/xml和application/xml | text/xml和application/xml |
MarshallingHttpMessageConverter | 使用Spring的Marshaller/Unmarshaller转换XML数据 | text/xml和application/xml | text/xml和application/xml |
MappingJackson2HttpMessageConverter | 使用Jackson的ObjectMapper转换Json数据 | application/json | application/json |
MappingJackson2XmlHttpMessageConverter | 使用Jackson的XmlMapper转换XML数据 | application/xml application/xml | |
BufferedImageHttpMessageConverter | 数据与java.awt.image.BufferedImage的相互转换 Java I/O API支持的所有类型 | Java I/O API支持的所有类型 |
重写MappingJackson2HttpMessageConverter
@Bean public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.TIME_PATTERN_DEFAULT)); mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); converter.setObjectMapper(mapper); return converter; }
配置FastJsonHttpMessageConverter
import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import java.nio.charset.Charset; @Configuration public class HttpMessageConverterConfig { //引入Fastjson解析json,不使用默认的jackson //必须在pom.xml引入fastjson的jar包,并且版必须大于1.2.10 @Bean public HttpMessageConverters fastJsonHttpMessageConverters() { //1、定义一个convert转换消息的对象 FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); //2、添加fastjson的配置信息 FastJsonConfig fastJsonConfig = new FastJsonConfig(); SerializerFeature[] serializerFeatures = new SerializerFeature[]{ // 输出key是包含双引号 // SerializerFeature.QuoteFieldNames, // 是否输出为null的字段,若为null 则显示该字段 // SerializerFeature.WriteMapNullValue, // 数值字段如果为null,则输出为0 SerializerFeature.WriteNullNumberAsZero, // List字段如果为null,输出为[],而非null SerializerFeature.WriteNullListAsEmpty, // 字符类型字段如果为null,输出为"",而非null SerializerFeature.WriteNullStringAsEmpty, // Boolean字段如果为null,输出为false,而非null SerializerFeature.WriteNullBooleanAsFalse, // Date的日期转换器 SerializerFeature.WriteDateUseDateFormat, // 循环引用 SerializerFeature.DisableCircularReferenceDetect, }; fastJsonConfig.setSerializerFeatures(serializerFeatures); fastJsonConfig.setCharset(Charset.forName("UTF-8")); //3、在convert中添加配置信息 fastConverter.setFastJsonConfig(fastJsonConfig); //4、将convert添加到converters中 HttpMessageConverter<?> converter = fastConverter; return new HttpMessageConverters(converter); } }