ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

SpringBoot3整合FastJSON2:高性能JSON处理指南

SpringBoot3整合FastJSON2:高性能JSON处理指南

1. 为什么需要整合FastJSON2与SpringBoot3

在SpringBoot项目中,默认使用Jackson作为JSON序列化/反序列化工具。但实际开发中,很多团队会选择FastJSON2替代Jackson,主要基于以下考量:

  1. 性能优势:FastJSON2在序列化速度上比Jackson快30%-50%,特别是在处理复杂嵌套对象时优势更明显
  2. 内存效率:FastJSON2的内存占用比Jackson低约20%,对于高并发场景更友好
  3. 灵活配置:支持更丰富的日期格式、空值处理等定制化配置
  4. 中文支持:对中文序列化的处理更加符合国内开发者的习惯

注意:从FastJSON1升级到FastJSON2时需要注意,两者API存在不兼容改动,建议直接使用FastJSON2的最新稳定版

2. 基础环境准备

2.1 依赖配置

首先在pom.xml中添加必要依赖(以SpringBoot 3.1.x为例):

<dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.34</version> </dependency> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2-extension-spring6</artifactId> <version>2.0.34</version> </dependency>

关键版本说明:

  • fastjson2要求JDK11+
  • spring6扩展包专门适配Spring6/SpringBoot3
  • 建议保持主包和扩展包版本一致

2.2 基础配置类

创建基础配置类FastJsonConfig:

@Configuration public class FastJsonConfiguration { @Bean public FastJsonConfig fastJsonConfig() { FastJsonConfig config = new FastJsonConfig(); config.setDateFormat("yyyy-MM-dd HH:mm:ss"); config.setWriterFeatures( WriterFeature.PrettyFormat, WriterFeature.WriteMapNullValue ); config.setReaderFeatures( ReaderFeature.AllowUnQuotedFieldNames ); return config; } }

3. 核心配置实现

3.1 配置MessageConverters的三种方式

方式一:完全替换默认Converter(推荐)
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired private FastJsonConfig fastJsonConfig; @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // 清空默认转换器 converters.clear(); // 创建FastJson转换器 FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); converter.setFastJsonConfig(fastJsonConfig); // 设置支持的MediaType List<MediaType> mediaTypes = new ArrayList<>(); mediaTypes.add(MediaType.APPLICATION_JSON); mediaTypes.add(MediaType.TEXT_PLAIN); converter.setSupportedMediaTypes(mediaTypes); converters.add(converter); } }
方式二:保留其他Converter,仅添加FastJson
@Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); converter.setFastJsonConfig(fastJsonConfig); // 插入到转换器列表首位 converters.add(0, converter); }
方式三:通过Bean声明方式
@Bean public HttpMessageConverters customConverters() { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); converter.setFastJsonConfig(fastJsonConfig); return new HttpMessageConverters(true, Arrays.asList(converter)); }

3.2 配置项详解

FastJsonConfig的核心可配置项:

配置项类型说明示例值
dateFormatString日期格式"yyyy-MM-dd"
writerFeaturesWriterFeature[]序列化特性WriteNullListAsEmpty
readerFeaturesReaderFeature[]反序列化特性SupportAutoType
serializerFeaturesSerializerFeature[]序列化特性(兼容旧版)PrettyFormat
charsetCharset字符编码StandardCharsets.UTF_8

常用Feature组合:

// 序列化配置 config.setWriterFeatures( WriterFeature.PrettyFormat, WriterFeature.WriteMapNullValue, WriterFeature.WriteNullListAsEmpty ); // 反序列化配置 config.setReaderFeatures( ReaderFeature.AllowUnQuotedFieldNames, ReaderFeature.SupportAutoType );

4. 高级配置技巧

4.1 自定义序列化规则

实现ObjectSerializer接口处理特殊类型:

public class MoneySerializer implements ObjectSerializer { @Override public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { BigDecimal value = (BigDecimal) object; String text = value.setScale(2, RoundingMode.HALF_UP) + "元"; serializer.write(text); } } // 注册自定义序列化器 fastJsonConfig.getSerializeConfig().put(BigDecimal.class, new MoneySerializer());

4.2 处理循环引用

// 方式1:全局配置 fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); // 方式2:局部注解 @JSONField(serializeFeatures = SerializerFeature.DisableCircularReferenceDetect) private User parent;

4.3 安全配置建议

// 关闭autotype功能(防攻击) fastJsonConfig.setReaderFeatures( ReaderFeature.SupportAutoType.masked() ); // 添加安全白名单 ParserConfig.getGlobalInstance().addAccept("com.yourpackage.model.");

5. 常见问题排查

5.1 日期格式化不生效

可能原因:

  1. 配置顺序问题:确保FastJsonConfig先于MessageConverter创建
  2. 局部注解覆盖:检查是否有@JSONField(format="...")覆盖全局配置
  3. 时区问题:建议显式设置时区
fastJsonConfig.setDateFormat("yyyy-MM-dd"); fastJsonConfig.setWriterFeatures(WriterFeature.WriteDateUseDateFormat);

5.2 中文乱码问题

解决方案:

  1. 确保Converter设置了UTF-8编码
  2. 检查HTTP响应头Content-Type
converter.setDefaultCharset(StandardCharsets.UTF_8); List<MediaType> mediaTypes = new ArrayList<>(); mediaTypes.add(new MediaType("application", "json", StandardCharsets.UTF_8)); converter.setSupportedMediaTypes(mediaTypes);

5.3 与Swagger的兼容问题

解决方法:

  1. 调整Converter顺序,让Swagger的Converter优先
  2. 或为Swagger添加专属配置:
@Bean public WebMvcConfigurer swaggerConverterConfigurer() { return new WebMvcConfigurer() { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { converters.removeIf(c -> c instanceof MappingJackson2HttpMessageConverter); converters.add(new MappingJackson2HttpMessageConverter()); } }; }

6. 性能优化建议

  1. 重用配置实例:将FastJsonConfig声明为单例Bean
  2. 合理使用缓存:对不变的对象开启序列化缓存
  3. 选择性序列化:使用@JSONField(serialize=false)忽略不必要字段
  4. 线程安全配置:ParserConfig和SerializeConfig全局配置要谨慎修改
// 启用序列化缓存(适合不变对象) fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteClassName);

实测对比(10000次序列化):

序列化方式平均耗时(ms)内存占用(MB)
Jackson45235
FastJSON2默认31828
FastJSON2优化后27522

7. 完整配置示例

@Configuration public class FastJsonConfigComplete { @Bean @Primary public FastJsonConfig fastJsonConfig() { FastJsonConfig config = new FastJsonConfig(); // 基础配置 config.setDateFormat("yyyy-MM-dd HH:mm:ss"); config.setCharset(StandardCharsets.UTF_8); // 序列化配置 config.setWriterFeatures( WriterFeature.PrettyFormat, WriterFeature.WriteMapNullValue, WriterFeature.WriteNullListAsEmpty, WriterFeature.WriteDateUseDateFormat ); // 反序列化配置 config.setReaderFeatures( ReaderFeature.AllowUnQuotedFieldNames, ReaderFeature.SupportArrayToBean ); // 安全配置 ParserConfig.getGlobalInstance().setAutoTypeSupport(false); ParserConfig.getGlobalInstance().addAccept("com.example.model."); // 自定义序列化 config.getSerializeConfig().put(BigDecimal.class, new MoneySerializer()); return config; } @Bean public HttpMessageConverters fastJsonConverters(FastJsonConfig fastJsonConfig) { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); converter.setFastJsonConfig(fastJsonConfig); List<MediaType> mediaTypes = new ArrayList<>(); mediaTypes.add(MediaType.APPLICATION_JSON); mediaTypes.add(MediaType.TEXT_PLAIN); converter.setSupportedMediaTypes(mediaTypes); return new HttpMessageConverters(converter); } }

8. 版本兼容性说明

不同环境下的适配方案:

SpringBoot版本FastJSON2版本注意事项
3.x2.0.26+必须使用fastjson2-extension-spring6
2.7.x2.0.14+使用fastjson2-extension-spring5
JDK版本≥11FastJSON2不再支持JDK8

迁移注意事项:

  1. 从FastJSON1迁移时,注意包名从com.alibaba.fastjson改为com.alibaba.fastjson2
  2. 部分API进行了重构,如JSON.parseObject()现在返回泛型对象
  3. 默认关闭了autotype功能,需要显式配置白名单
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进