SpringBoot2.0如何集成fastjson?在网上查了一堆资料,但是各文章的说法不一,有些还是错的,可能只是简单测试一下就认为ok了,最后有没生效都不知道。恰逢公司项目需要将JackSon换成fastjson,因此自己来实践一下SpringBoot2.0和fastjson的整合,同时记录下来方便自己后续查阅。
一、Maven依赖说明
SpringBoot的版本为: <version>2.1.4.RELEASE</version>
在pom文件中添加fastjson的依赖:
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
6
1
<!-- fastjson -->
2
<dependency>
3
<groupId>com.alibaba</groupId>
4
<artifactId>fastjson</artifactId>
5
<version>1.2.56</version>
6
</dependency>
二、整合
我们写一个配置类WebConfig实现WebMvcConfigurer接口,然后重写configureMessageConverters方法。具体的代码如下:
package com.psx.gqxy.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
/**
* web相关的定制化配置
* @author ZENG.XIAO.YAN
* @version 1.0
* @Date 9012-88-88
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
// WebMvcConfigurerAdapter 这个类在SpringBoot2.0已过时,官方推荐直接实现WebMvcConfigurer 这个接口
/**
* 使用fastjson代替jackson
* @param converters
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
/*
先把JackSon的消息转换器删除.
备注: (1)源码分析可知,返回json的过程为:
Controller调用结束后返回一个数据对象,for循环遍历conventers,找到支持application/json的HttpMessageConverter,然后将返回的数据序列化成json。
具体参考org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法
(2)由于是list结构,我们添加的fastjson在最后。因此必须要将jackson的转换器删除,不然会先匹配上jackson,导致没使用fastjson
*/
for (int i = converters.size() - 1; i >= 0; i--) {
if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
converters.remove(i);
}
}
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
//自定义fastjson配置
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(
SerializerFeature.WriteMapNullValue, // 是否输出值为null的字段,默认为false,我们将它打开
SerializerFeature.WriteNullListAsEmpty, // 将Collection类型字段的字段空值输出为[]
SerializerFeature.WriteNullStringAsEmpty, // 将字符串类型字段的空值输出为空字符串
SerializerFeature.WriteNullNumberAsZero, // 将数值类型字段的空值输出为0
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.DisableCircularReferenceDetect // 禁用循环引用
);
fastJsonHttpMessageConverter.setFastJsonConfig(config);
// 添加支持的MediaTypes;不添加时默认为*/*,也就是默认支持全部
// 但是MappingJackson2HttpMessageConverter里面支持的MediaTypes为application/json
// 参考它的做法, fastjson也只添加application/json的MediaType
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
converters.add(fastJsonHttpMessageConverter);
}
}
65
1
package com.psx.gqxy.config;
2
3
import com.alibaba.fastjson.serializer.SerializerFeature;
4
import com.alibaba.fastjson.support.config.FastJsonConfig;
5
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
6
import org.springframework.context.annotation.Configuration;
7
import org.springframework.http.MediaType;
8
import org.springframework.http.converter.HttpMessageConverter;
9
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
10
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
11
import java.util.ArrayList;
12
import java.util.List;
13
14
/**
15
* web相关的定制化配置
16
* @author ZENG.XIAO.YAN
17
* @version 1.0
18
* @Date 9012-88-88
19
*/
20
21
public class WebConfig implements WebMvcConfigurer {
22
// WebMvcConfigurerAdapter 这个类在SpringBoot2.0已过时,官方推荐直接实现WebMvcConfigurer 这个接口
23
24
/**
25
* 使用fastjson代替jackson
26
* @param converters
27
*/
28
29
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
30
/*
31
先把JackSon的消息转换器删除.
32
备注: (1)源码分析可知,返回json的过程为:
33
Controller调用结束后返回一个数据对象,for循环遍历conventers,找到支持application/json的HttpMessageConverter,然后将返回的数据序列化成json。
34
具体参考org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法
35
(2)由于是list结构,我们添加的fastjson在最后。因此必须要将jackson的转换器删除,不然会先匹配上jackson,导致没使用fastjson
36
*/
37
for (int i = converters.size() - 1; i >= 0; i--) {
38
if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
39
converters.remove(i);
40
}
41
}
42
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
43
44
//自定义fastjson配置
45
FastJsonConfig config = new FastJsonConfig();
46
config.setSerializerFeatures(
47
SerializerFeature.WriteMapNullValue, // 是否输出值为null的字段,默认为false,我们将它打开
48
SerializerFeature.WriteNullListAsEmpty, // 将Collection类型字段的字段空值输出为[]
49
SerializerFeature.WriteNullStringAsEmpty, // 将字符串类型字段的空值输出为空字符串
50
SerializerFeature.WriteNullNumberAsZero, // 将数值类型字段的空值输出为0
51
SerializerFeature.WriteDateUseDateFormat,
52
SerializerFeature.DisableCircularReferenceDetect // 禁用循环引用
53
);
54
fastJsonHttpMessageConverter.setFastJsonConfig(config);
55
56
// 添加支持的MediaTypes;不添加时默认为*/*,也就是默认支持全部
57
// 但是MappingJackson2HttpMessageConverter里面支持的MediaTypes为application/json
58
// 参考它的做法, fastjson也只添加application/json的MediaType
59
List<MediaType> fastMediaTypes = new ArrayList<>();
60
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
61
fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
62
converters.add(fastJsonHttpMessageConverter);
63
}
64
}
65
三、测试
(1)代码
要测试fastjson是否整合成功的话,我们只需要在实体类中使用一下fastjson的注解就ok。如果注解生效了,说明fastjson整合成功了。直接看代码
package com.psx.gqxy.web.controller;
import com.alibaba.fastjson.annotation.JSONField;
import com.psx.gqxy.common.base.ModelResult;
import lombok.Data;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
/**
* TestController
* @author ZENG.XIAO.YAN
* @version 1.0
* @Date 9012-88-88
*/
@RestController
public class TestController {
@GetMapping("/json")
public ModelResult<JsonBean> testJson() {
ModelResult<JsonBean> result = new ModelResult<>();
JsonBean jsonBean = new JsonBean();
jsonBean.setBirthDay(new Date());
jsonBean.setName("测试");
result.setData(jsonBean);
// 效果
/*{
"code": "200",
"data": {
"birthDay": "2019年05月12日",
"name": "测试",
"qqList": []
},
"msg": ""
}*/
return result;
}
@Data
class JsonBean {
private String name;
@JSONField(format = "yyyy年MM月dd日")
private Date birthDay;
private List<String> qqList;
}
}
49
1
package com.psx.gqxy.web.controller;
2
3
import com.alibaba.fastjson.annotation.JSONField;
4
import com.psx.gqxy.common.base.ModelResult;
5
import lombok.Data;
6
import org.springframework.web.bind.annotation.GetMapping;
7
import org.springframework.web.bind.annotation.RestController;
8
import java.util.Date;
9
import java.util.List;
10
11
/**
12
* TestController
13
* @author ZENG.XIAO.YAN
14
* @version 1.0
15
* @Date 9012-88-88
16
*/
17
18
public class TestController {
19
20
"/json") (
21
public ModelResult<JsonBean> testJson() {
22
ModelResult<JsonBean> result = new ModelResult<>();
23
JsonBean jsonBean = new JsonBean();
24
jsonBean.setBirthDay(new Date());
25
jsonBean.setName("测试");
26
result.setData(jsonBean);
27
// 效果
28
/*{
29
"code": "200",
30
"data": {
31
"birthDay": "2019年05月12日",
32
"name": "测试",
33
"qqList": []
34
},
35
"msg": ""
36
}*/
37
return result;
38
}
39
40
41
42
class JsonBean {
43
private String name;
44
format = "yyyy年MM月dd日") (
45
private Date birthDay;
46
private List<String> qqList;
47
}
48
}
49
(2)效果
通过这个2步的测试,发现fastjson的注解生效了,也就说明整合成功了
四、杂谈
SpringBoot2.0后,有些东西改变了。在SpringBoot 1.X时代,整合fastjson是可以不排除JackSon消息转换器的。但在SpringBoot2.X时代,必须要排除JackSon消息转换器。