SpringBoot2.0如何集成fastjson?在網上查了一堆資料,但是各文章的說法不一,有些還是錯的,可能只是簡單測試一下就認為ok了,最后有沒生效都不知道。恰逢公司項目需要將JackSon換成fastjson,因此自己來實踐一下SpringBoot2.0和fastjson的整合,同時記錄下來方便自己后續查閱。
一、Maven依賴說明
SpringBoot的版本為: <version>2.1.4.RELEASE</version>
在pom文件中添加fastjson的依賴:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.60/version> </dependency>
二、整合
整合之前,我們先說下springboot1.0的方法,輕車熟路的去自定了一個SpringMvcConfigure
去繼承WebMvcConfigurerAdapter
,然后你就發現這個WebMvcConfigurerAdapter
竟然過時了?what?點進去看源碼:
1 /** 2 * An implementation of {@link WebMvcConfigurer} with empty methods allowing 3 * subclasses to override only the methods they're interested in. 4 * 5 * @author Rossen Stoyanchev 6 * @since 3.1 7 * @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made 8 * possible by a Java 8 baseline) and can be implemented directly without the 9 * need for this adapter 10 */ 11 @Deprecated 12 public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {}
可以看到從spring5.0開始就被@Deprecated,原來是java8中支持接口中有默認方法,所以我們現在可以直接實現
WebMvcConfigurer
,然后選擇性的去重寫某個方法,而不用實現它的所有方法.
於是就實現了
WebMvcConfigurer
:
1 @Configuration 2 public class SpringMvcConfigure implements WebMvcConfigurer { 3 4 /** 5 * 配置消息轉換器 6 * @param converters 7 */ 8 @Override 9 public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 10 FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); 11 //自定義配置... 12 FastJsonConfig config = new FastJsonConfig(); 13 config.setSerializerFeatures(SerializerFeature.QuoteFieldNames, 14 SerializerFeature.WriteEnumUsingToString, 15 /*SerializerFeature.WriteMapNullValue,*/ 16 SerializerFeature.WriteDateUseDateFormat, 17 SerializerFeature.DisableCircularReferenceDetect); 18 fastJsonHttpMessageConverter.setFastJsonConfig(config); 19 converters.add(fastJsonHttpMessageConverter); 20 } 21 22 }
本以為這樣子配置就可以完事兒,但是詭異的事情發生了,我明明注釋了
SerializerFeature.WriteMapNullValue
,可是返回的json中仍然有為null
的字段,然后我就去com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter
中的write
和writeInternal
打了斷點,再次執行,竟然什么都沒有發生,根本沒有走這兩個方法,於是在自定義的SpringMvcConfigure
中configureMessageConverters
方法內打了斷點,想看看這個方法參數converters
里邊到底有什么:

看到這里就想到,肯定是我自己添加的fastjson在后邊,所以沒有生效,所以就加了以下代碼:
1 @Override 2 public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 3 converters = converters.stream() 4 .filter((converter)-> !(converter instanceof MappingJackson2HttpMessageConverter)) 5 .collect(Collectors.toList()); 6 FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); 7 //自定義配置... 8 FastJsonConfig config = new FastJsonConfig(); 9 config.setSerializerFeatures(SerializerFeature.QuoteFieldNames, 10 SerializerFeature.WriteEnumUsingToString, 11 /*SerializerFeature.WriteMapNullValue,*/ 12 SerializerFeature.WriteDateUseDateFormat, 13 SerializerFeature.DisableCircularReferenceDetect); 14 fastJsonHttpMessageConverter.setFastJsonConfig(config); 15 converters.add(fastJsonHttpMessageConverter); 16 }
這還是不生效的,繼續追蹤,得出如下結論:
(1)源碼分析可知,返回json的過程為:
Controller調用結束后返回一個數據對象,for循環遍歷conventers,找到支持application/json的HttpMessageConverter,然后將返回的數據序列化成json。
具體參考org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法
(2)由於是list結構,我們添加的fastjson在最后。因此必須要將jackson的轉換器刪除,不然會先匹配上jackson,導致沒使用fastjson
最終得出代碼如下:
1 @Configuration 2 public class SpringWebMvcConfigurer implements WebMvcConfigurer { 3 4 private final Logger logger = LoggerFactory.getLogger(SpringWebMvcConfigurer.class); 5 6 //使用阿里 FastJson 作為JSON MessageConverter 7 @Override 8 public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 9 10 /* 11 先把JackSon的消息轉換器刪除. 12 備注: (1)源碼分析可知,返回json的過程為: 13 Controller調用結束后返回一個數據對象,for循環遍歷conventers,找到支持application/json的HttpMessageConverter,然后將返回的數據序列化成json。 14 具體參考org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法 15 (2)由於是list結構,我們添加的fastjson在最后。因此必須要將jackson的轉換器刪除,不然會先匹配上jackson,導致沒使用fastjson 16 */ 17 for (int i = converters.size() - 1; i >= 0; i--) { 18 if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) { 19 converters.remove(i); 20 } 21 } 22 23 FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); 24 FastJsonConfig config = new FastJsonConfig(); 25 config.setSerializerFeatures( 26 SerializerFeature.WriteMapNullValue,//保留空的字段 27 SerializerFeature.WriteNullStringAsEmpty,//String null -> "" 28 SerializerFeature.WriteNullNumberAsZero,//Number null -> 0 29 SerializerFeature.WriteDateUseDateFormat);//日期格式化 30 31 converter.setFastJsonConfig(config); 32 converter.setDefaultCharset(Charset.forName("UTF-8")); 33 converters.add(converter); 34 } 35 }
總結
- 最重要的還是解決了springboot2.0.2配置fastjson不生效的問題
- 更加明白stream api返回的都是全新的對象
- 更理解java是值傳遞而不是引用傳遞
- 了解到想要在迭代過程中對集合進行操作要用Iterator,而不是直接簡單的for循環或者增強for循環