FastJSON 实战完整指南:高性能特性 + 必踩深坑全覆盖
2026/6/10 13:01:23 网站建设 项目流程

FastJSON 实战完整指南:高性能特性 + 必踩深坑全覆盖

一、基础认知:FastJSON1 vs FastJSON2(核心区分)

1. 版本定位

  • FastJSON 1.x(com.alibaba:fastjson):初代版本,存在大量高危反序列化漏洞,生产禁止使用,仅历史遗留项目;最高安全修复版1.2.83,但仍有架构底层缺陷。
  • FastJSON 2.x(com.alibaba.fastjson2:fastjson2):重构全新架构,安全机制重写、性能翻倍,官方主推,企业新项目统一使用。

2. 核心优势(高性能来源)

  1. 自研序列化/反序列化字节流解析,不依赖反射循环,吞吐量高于Jackson、Gson;
  2. 内置完整注解体系、日期/枚举/泛型自动适配;
  3. 支持序列化过滤、格式化、JSONPath、流式超大JSON读写;
  4. 兼容标准JSON、JSON5、二进制JSONB格式。

二、标准实战基础用法(FastJSON2 规范写法)

1. 序列化(对象 → JSON字符串)

Useruser=newUser(1L,"张三",LocalDateTime.now());// 基础序列化StringjsonStr=JSON.toJSONString(user);// 格式化输出、忽略null值、日期格式化StringprettyJson=JSON.toJSONString(user,SerializerFeature.PrettyFormat,SerializerFeature.WriteDateUseDateFormat,SerializerFeature.WriteNonStringKeyAsString);

2. 反序列化(JSON → 对象)

Stringjson="{\"id\":1,\"name\":\"张三\"}";// 普通对象Useruser=JSON.parseObject(json,User.class);// 泛型集合List<User>userList=JSON.parseArray(json,User.class);// 泛型复杂DTOResultDTO<User>dto=JSON.parseObject(json,newTypeReference<ResultDTO<User>>(){});

3. 注解定制序列化

@DatapublicclassUser{privateLongid;// 自定义JSON字段名@JSONField(name="username")privateStringname;// 日期格式化@JSONField(format="yyyy-MM-dd HH:mm:ss")privateLocalDateTimecreateTime;// 序列化忽略此字段@JSONField(serialize=false)privateStringpassword;}

三、生产环境必避致命大坑(分维度整理)

(一)安全类高危坑(线上漏洞根源)

坑1:FastJSON 1.x 任意代码执行漏洞(最严重)

  1. 原理:1.x 默认开启autoTypeSupport,反序列化时可通过@type指定任意类,触发恶意类构造执行命令;
  2. 风险:攻击者构造恶意JSON,远程服务器执行系统命令、读取文件;
  3. 解决方案:
    • 新项目直接升级FastJSON2
    • 遗留1.x项目强制关闭自动类型,白名单限制类:
      // 全局关闭autoTypeParserConfig.getGlobalInstance().setAutoTypeSupport(false);// 业务类加入白名单ParserConfig.getGlobalInstance().addAccept("com.xxx.biz.entity");

坑2:FastJSON2 autoType 误用风险

FastJSON2默认关闭自动类型,但手动开启后仍存在风险,禁止全局开启autoTypeSupport,仅在可控接口局部开启并配置白名单。

坑3:JSON注入风险

序列化用户输入时,特殊字符</script>&、引号未转义,前端渲染触发XSS;
修复:序列化时增加转义特性:

JSON.toJSONString(obj,SerializerFeature.BrowserSecure);

(二)序列化数据转换坑(高频业务报错)

坑4:数字精度丢失(Long、BigDecimal 经典问题)

场景:前端传输雪花ID(19位Long),FastJSON默认将大数字序列化为数字类型,JS Number精度丢失;
错误输出:{"userId":1423874129837412938}
正确方案:强制将Long序列化输出字符串:

// 全局配置JSON.config(JSONWriter.Feature.WriteLongAsString);// 单次序列化指定JSON.toJSONString(user,SerializerFeature.WriteNonStringKeyAsString);// 字段单独注解@JSONField(serializeUsing=LongToStringSerializer.class)privateLonguserId;

坑5:日期类兼容灾难(LocalDateTime、Date、Timestamp 格式错乱)

  1. 问题1:无注解时LocalDateTime序列化为数组[2026,6,9,14,20],前端无法解析;
  2. 问题2:Date默认输出毫秒时间戳,前后端格式不统一;
    修复方案二选一:
  3. 字段注解固定格式@JSONField(format = "yyyy-MM-dd HH:mm:ss")
  4. 全局配置日期格式化:
    JSON.config(JSONReader.Feature.SupportSmartDate);JSON.config(JSONWriter.Feature.WriteDateUseDateFormat);

坑6:null值默认不输出,前端字段缺失报错

FastJSON默认过滤值为null的字段,前端JS读取undefined引发异常;
解决方案:序列化时开启输出null:

JSON.toJSONString(obj,SerializerFeature.WriteMapNullValue);

配套空值填充规则:字符串null输出空串、数字null输出0

SerializerFeature.WriteNullStringAsEmpty,SerializerFeature.WriteNullNumberAsZero

坑7:枚举序列化默认输出name(),前端需要code值

默认枚举序列化输出枚举名称{"status":"NORMAL"},业务需要编码{"status":0}
修复:实现JSONSerializable自定义枚举序列化,或使用注解@JSONField(serializeUsing)

(三)反序列化解析坑(线上500高发)

坑8:泛型、嵌套泛型解析丢失类型

直接parseObject(json, ResultDTO.class)会丢失泛型T的类型,对象内部字段解析为JSONObject;
必须使用TypeReference捕获泛型

// 正确写法ResultDTO<User>result=JSON.parseObject(json,newTypeReference<ResultDTO<User>>(){});// 错误写法,泛型丢失ResultDTO<User>result=JSON.parseObject(json,ResultDTO.class);

坑9:驼峰/下划线字段自动匹配失效

前端传下划线user_name,后端实体驼峰userName,FastJSON默认不自动兼容;
全局开启下划线兼容:

ParserConfig.getGlobalInstance().setCompatibleWithJavaBean(true);JSON.config(JSONReader.Feature.AllowUnQuotedFieldNames);

坑10:空字符串反序列化数字/日期直接抛异常

前端传{"age":""},反序列化Integer字段直接抛出类型转换异常;
解决方案:

  1. 全局配置开启智能兼容空串:JSONReader.Feature.SupportCompatibleEmptyString
  2. 自定义反序列化处理器,空串转为null/默认值。

坑11:超大JSON文件OOM内存溢出

一次性读取GB级JSON字符串,全部加载到堆内存;
正确流式API,分段读写,不占用完整堆:

// 流式读取大文件JSONtry(JsonReaderreader=JSONReader.of(newFileInputStream("big.json"))){while(reader.hasNext()){Useruser=reader.readObject(User.class);}}

(四)框架整合与性能坑

坑12:SpringMVC 全局消息转换器配置冲突

项目同时引入Jackson + FastJSON,MVC优先使用Jackson,FastJSON配置不生效;
标准FastJSON2 WebMvc配置:

@ConfigurationpublicclassFastJsonConfigimplementsWebMvcConfigurer{@OverridepublicvoidconfigureMessageConverters(List<HttpMessageConverter<?>>converters){FastJson2HttpMessageConverterconverter=newFastJson2HttpMessageConverter();// 全局序列化特性统一配置JSONWriter.Feature[]features={JSONWriter.Feature.WriteLongAsString,JSONWriter.Feature.WriteMapNullValue,JSONWriter.Feature.WriteDateUseDateFormat};converter.setWriterFeatures(features);converters.add(0,converter);// 放到首位优先执行}}

坑13:频繁创建ParserConfig、TypeReference引发GC飙升

  1. TypeReference每次new会创建匿名内部类,大量循环内创建导致元空间上涨;解决方案:静态常量复用TypeReference;
  2. ParserConfig全局单例,禁止在循环中new ParserConfig实例。

坑14:序列化循环引用直接栈溢出

实体存在双向关联(User ↔ Order),互相引用序列化触发StackOverflowError;
解决方案:

  1. 字段忽略:@JSONField(serialize = false)
  2. 开启循环引用检测:
    JSON.toJSONString(user,SerializerFeature.DisableCircularReferenceDetect);

(五)版本依赖坑

坑15:混合引入FastJSON1 + FastJSON2 包冲突

同时引入fastjsonfastjson2,类路径冲突,随机抛出类转换异常;
Maven统一依赖,仅保留FastJSON2:

<!-- 正确依赖 FastJSON2 最新稳定版 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.48</version></dependency><!-- 移除旧版fastjson 1.x --><!-- <dependency>com.alibaba:fastjson</dependency> -->

坑16:低版本FastJSON2存在内存泄漏

2.0.30以下版本流式API存在缓冲区泄漏,建议统一升级至2.0.40+稳定版。


四、生产环境标准化最佳实践

  1. 版本强制规范:新项目统一FastJSON2 2.0.48+,彻底下线FastJSON1;
  2. 全局统一序列化规则:Web消息转换器统一配置:Long转字符串、输出null、日期格式化、XSS转义;
  3. 安全管控:全局关闭autoType,仅可控场景白名单开放类型;
  4. 泛型规范:所有带泛型的反序列化,必须复用静态TypeReference;
  5. 大文件处理:一律使用流式JsonReader/JsonWriter,禁止一次性加载完整JSON字符串;
  6. 实体规范:日期、Long主键、密码敏感字段统一加@JSONField注解;
  7. 循环引用:业务DO双向关联字段直接关闭序列化,避免检测带来性能损耗。

五、FastJSON vs Jackson 选型对比补充

维度FastJSON2Jackson
序列化性能更高(字节流解析)中等
安全机制默认关闭autoType,漏洞防护完善无远程执行风险
注解易用性@JSONField轻量化@JsonProperty配置繁琐
大JSON流式支持原生完善需要手动封装
企业生态阿里中间件、国内微服务适配好SpringBoot默认内置

选型建议

  1. 国内电商、大数据、高吞吐接口项目:优先FastJSON2;
  2. 简单单体Spring项目、无大量JSON处理:使用原生Jackson减少第三方依赖。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询