1. 问题复现当FastJsonHttpMessageConverter突然消失最近在升级Spring Boot项目中的FastJson依赖时我遇到了一个典型的找不到类错误。原本运行良好的代码突然在编译时报错提示FastJsonHttpMessageConverter和FastJsonConfig类不存在。这种情况在从FastJson1升级到FastJson2时特别常见因为Alibaba团队对包结构进行了重大调整。我当时的错误堆栈是这样的java: 找不到符号 符号: 类 FastJsonHttpMessageConverter 位置: 程序包 com.alibaba.fastjson.support.spring这个问题看似简单实则暗藏玄机。FastJson2不仅改变了包路径还将功能模块拆分成了多个子项目。很多开发者包括我最初的反应是明明已经更新了依赖为什么还是找不到类 这正是FastJson2升级过程中的第一个坑——你以为只更新主依赖就够了实际上需要一组配套依赖。2. 源码结构分析FastJson1 vs FastJson2的包路径差异为了彻底理解这个问题我专门对比了两个版本的源码结构。在FastJson1中所有功能都集中在一个JAR包里com.alibaba.fastjson └── support ├── config │ └── FastJsonConfig └── spring └── FastJsonHttpMessageConverter而FastJson2采用了模块化设计将不同功能拆分到多个子项目中com.alibaba.fastjson2 ├── support │ └── config │ └── FastJsonConfig (来自fastjson2-extension) └── support └── spring6 └── http └── converter └── FastJsonHttpMessageConverter (来自fastjson2-extension-spring6)这种结构调整带来了几个关键变化基础包名从com.alibaba.fastjson变为com.alibaba.fastjson2Spring相关的消息转换器被移到了单独的扩展模块针对不同Spring版本提供了专门的适配器如spring5、spring63. 正确的Maven依赖组合经过反复试验我发现要完整支持FastJson2在Spring项目中的使用需要以下三个核心依赖!-- 核心库 -- dependency groupIdcom.alibaba.fastjson2/groupId artifactIdfastjson2/artifactId version2.0.49/version /dependency !-- 扩展功能包含FastJsonConfig -- dependency groupIdcom.alibaba.fastjson2/groupId artifactIdfastjson2-extension/artifactId version2.0.49/version /dependency !-- Spring6专用适配器包含FastJsonHttpMessageConverter -- dependency groupIdcom.alibaba.fastjson2/groupId artifactIdfastjson2-extension-spring6/artifactId version2.0.49/version /dependency这里有个容易忽略的细节如果你的项目使用的是Spring 5.x应该使用fastjson2-extension-spring5而不是spring6版本。版本不匹配会导致类加载失败这是第二个常见的坑。4. 适配Spring 6的配置代码重写依赖问题解决后接下来需要更新消息转换器的配置代码。以下是完整的配置示例import com.alibaba.fastjson2.support.config.FastJsonConfig; import com.alibaba.fastjson2.support.spring6.http.converter.FastJsonHttpMessageConverter; Configuration public class WebMvcConfig implements WebMvcConfigurer { Override public void configureMessageConverters(ListHttpMessageConverter? converters) { FastJsonHttpMessageConverter converter new FastJsonHttpMessageConverter(); // 配置序列化规则 FastJsonConfig config new FastJsonConfig(); config.setDateFormat(yyyy-MM-dd HH:mm:ss); config.setCharset(StandardCharsets.UTF_8); // 启用高级特性 config.setReaderFeatures( JSONReader.Feature.FieldBased, JSONReader.Feature.SupportArrayToBean ); config.setWriterFeatures( JSONWriter.Feature.WriteMapNullValue, JSONWriter.Feature.PrettyFormat ); converter.setFastJsonConfig(config); converter.setDefaultCharset(StandardCharsets.UTF_8); converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON)); // 优先使用FastJson转换器 converters.add(0, converter); } }与旧版相比新版配置有几个重要改进点移除了过时的MediaType.APPLICATION_JSON_UTF8Spring 6已废弃支持更精细化的读写特性配置提供了更好的null值处理支持日期格式配置更加直观5. 常见问题排查与验证完成上述步骤后建议通过以下方式验证配置是否生效测试用例1检查JSON序列化RestController public class TestController { GetMapping(/test) public Object test() { MapString, Object data new HashMap(); data.put(name, 张三); data.put(age, null); // 测试null值处理 data.put(createTime, new Date()); return data; } }预期输出应该包含格式化日期和保留的null值字段{ name: 张三, age: null, createTime: 2024-03-20 14:30:00 }测试用例2验证中文编码GetMapping(/chinese) public Object chineseTest() { return Collections.singletonMap(message, 中文测试); }响应头应该正确显示Content-Type: application/json;charsetUTF-8如果遇到问题可以按以下步骤排查检查依赖树是否有版本冲突mvn dependency:tree确认导入的类来自正确的包路径调试时在configureMessageConverters方法内打断点检查converters列表检查Spring Boot的自动配置是否覆盖了你的设置6. 性能优化建议FastJson2相比v1版本在性能上有显著提升但通过合理配置可以进一步优化启用ASM加速FastJsonConfig config new FastJsonConfig(); config.setReaderFeatures(JSONReader.Feature.UseNativeObject); config.setWriterFeatures(JSONWriter.Feature.UseSingleQuotes);配置线程局部缓存// 在应用启动时执行 JSONFactory.setContextObjectReaderProvider(new DefaultObjectReaderProvider()); JSONFactory.setContextObjectWriterProvider(new DefaultObjectWriterProvider());针对高并发场景的调优config.setWriterFeatures( JSONWriter.Feature.WriteLongAsString, JSONWriter.Feature.LargeObject );安全加固配置config.setReaderFeatures( JSONReader.Feature.SupportAutoType, // 谨慎开启 JSONReader.Feature.ErrorOnUnknownProperties );7. 兼容性处理技巧对于需要同时兼容新旧JSON字段的项目可以使用以下策略字段别名配置JSONField(name old_name, alternateNames {new_name, deprecated_name}) private String fieldName;版本适配器模式public class ApiResultT { JSONField(serialize false) private T v1Data; JSONField(serialize false) private T v2Data; public static T ApiResultT fromV1(T data) { ApiResultT result new ApiResult(); result.v1Data data; return result; } JSONField(serialize true) public T getData() { return v2Data ! null ? v2Data : v1Data; } }自定义序列化器config.setWriterFeatures(JSONWriter.Feature.WriteClassName); config.setReaderFeatures(JSONReader.Feature.SupportAutoType);8. 实际项目中的经验分享在大型项目中升级JSON库时我总结了几个实用技巧渐进式迁移方案先在新接口中使用FastJson2逐步改造旧接口使用适配器模式处理新旧格式共存监控指标添加// 记录序列化耗时 long start System.nanoTime(); String json JSON.toJSONString(obj); Metrics.timer(json.serialize).record(System.nanoTime() - start, TimeUnit.NANOSECONDS); // 记录反序列化错误 try { Object obj JSON.parseObject(json, clazz); } catch (Exception e) { Metrics.counter(json.parse.error).increment(); }单元测试保障Test public void testDateSerialize() { Date now new Date(); String json JSON.toJSONString(now); Date parsed JSON.parseObject(json, Date.class); assertEquals(now.getTime() / 1000, parsed.getTime() / 1000); } Test public void testChineseEncoding() { String text 中文测试; String json JSON.toJSONString(text); assertEquals(\ text \, json); }回滚预案保留FastJson1的配置代码但注释掉准备快速切换的feature flag在灰度发布时密切监控JSON处理相关的异常