以下是一份系统性、综合性、全面的 FastJSON2 使用指南,专为 Java 后端开发者(使用 Spring Boot 等框架)量身定制,包含所有你要求的使用场景、详细示例、静态工具类说明、进阶用法(JSONB、JSONPath),以及最佳实践与推荐规则。
✅ FastJSON2 完全使用指南(Java 后端开发实战版)
FastJSON2 是阿里巴巴开源的高性能 JSON 库,是 FastJSON 1.x 的完全重构版本,性能提升显著(官方测试快 10 倍以上),支持 JSONB 二进制格式、JSONPath、安全反序列化、泛型处理等,是 Spring Boot 项目中推荐的 JSON 处理方案之一(尤其在高并发、低延迟场景)。
📌 一、引入依赖(Maven)
<!-- pom.xml -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.54</version> <!-- 建议使用最新稳定版 -->
</dependency>
✅ 推荐:在 Spring Boot 项目中,默认使用 Jackson。若需替换为 FastJSON2,需配置:
@Configuration public class JsonConfig { @Bean @Primary public ObjectMapper objectMapper() { return new ObjectMapper(); } @Bean public HttpMessageConverters fastJsonHttpMessageConverters() { FastJson2HttpMessageConverter converter = new FastJson2HttpMessageConverter(); FastJson2Config config = new FastJson2Config(); config.setSerializerFeatures( SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullListAsEmpty ); converter.setFastJson2Config(config); return new HttpMessageConverters(converter); } }
📌 二、常用使用场景与详细示例(含中文注释)
✅ 1. 将 JSON 字符串解析为 JSONObject
import com.alibaba.fastjson2.JSONObject;
String jsonStr = "{\"name\":\"张三\",\"age\":28,\"city\":\"北京\"}";
// 将 JSON 字符串解析为 JSONObject(类似 Map<String, Object>)
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
// 获取字段值(自动类型转换)
String name = jsonObject.getString("name"); // "张三"
Integer age = jsonObject.getInteger("age"); // 28
String city = jsonObject.getString("city"); // "北京"
// 安全获取(避免空指针)
String phone = jsonObject.getString("phone", "未提供"); // 若不存在,返回默认值
✅ 适用场景:动态解析 JSON 配置、接收第三方 API 返回的非结构化数据、日志分析。
✅ 2. 将 JSON 字符串解析为 JSONArray
import com.alibaba.fastjson2.JSONArray;
String jsonArrayStr = "[{\"id\":1,\"name\":\"苹果\"},{\"id\":2,\"name\":\"香蕉\"}]";
// 解析为 JSONArray(类似 List<Object>)
JSONArray jsonArray = JSONArray.parseArray(jsonArrayStr);
// 遍历数组
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject item = jsonArray.getJSONObject(i); // 获取每个元素为 JSONObject
Long id = item.getLong("id");
String name = item.getString("name");
System.out.println("第" + (i + 1) + "个水果: " + name + ", ID=" + id);
}
// 或使用增强 for 循环
for (Object obj : jsonArray) {
JSONObject fruit = (JSONObject) obj;
System.out.println("水果名:" + fruit.getString("name"));
}
✅ 适用场景:批量数据导入、分页列表响应、配置文件中的数组项处理。
✅ 3. 将 JSON 字符串解析为 Java 对象(POJO)
import com.alibaba.fastjson2.JSON;
// 定义 JavaBean
class Person {
private String name;
private Integer age;
private String city;
// 必须有无参构造函数(FastJSON2 要求)
public Person() {}
// Getter/Setter(推荐使用 Lombok 简化)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", city='" + city + "'}";
}
}
// JSON 字符串
String json = "{\"name\":\"李四\",\"age\":30,\"city\":\"上海\"}";
// 直接反序列化为 Person 对象
Person person = JSON.parseObject(json, Person.class);
System.out.println(person); // 输出:Person{name='李四', age=30, city='上海'}
// 支持泛型(如 List<Person>)
String listJson = "[{\"name\":\"王五\",\"age\":25},{\"name\":\"赵六\",\"age\":32}]";
List<Person> personList = JSON.parseObject(listJson, new TypeReference<List<Person>>() {});
✅ 注意:字段名必须与 JSON 键名匹配(默认大小写敏感)。如需忽略大小写,可配置:
JSON.parseObject(json, Person.class, JSONReader.Feature.IgnoreCaseMatch);
✅ 适用场景:REST API 请求体解析、配置文件加载、数据库字段 JSON 存储反序列化。
✅ 4. 将 Java 对象序列化为 JSON 字符串
Person person = new Person();
person.setName("王小明");
person.setAge(22);
person.setCity("广州");
// 序列化为 JSON 字符串
String json = JSON.toJSONString(person);
System.out.println(json); // 输出:{"name":"王小明","age":22,"city":"广州"}
// 序列化时忽略 null 值字段
String jsonNoNull = JSON.toJSONString(person, SerializerFeature.WriteMapNullValue);
// 默认不输出 null 字段,如需输出 null,需显式配置 WriteMapNullValue
// 格式化输出(带缩进)
String prettyJson = JSON.toJSONString(person, SerializerFeature.PrettyFormat);
System.out.println(prettyJson);
/*
输出:
{
"name": "王小明",
"age": 22,
"city": "广州"
}
*/
✅ 适用场景:API 响应返回、日志记录、缓存存储(如 Redis 存 JSON 字符串)。
✅ 5. 使用 JSONObject、JSONArray 动态构建与操作
// 动态构建 JSONObject
JSONObject user = new JSONObject();
user.put("username", "admin");
user.put("email", "admin@company.com");
user.put("isActive", true);
user.put("roles", new String[]{"ADMIN", "USER"}); // 自动转为 JSONArray
// 动态构建 JSONArray
JSONArray permissions = new JSONArray();
permissions.add("read");
permissions.add("write");
permissions.add("delete");
user.put("permissions", permissions);
// 添加嵌套对象
JSONObject profile = new JSONObject();
profile.put("avatar", "http://xxx.jpg");
profile.put("bio", "系统管理员");
user.put("profile", profile);
// 输出最终 JSON
System.out.println(user.toJSONString(SerializerFeature.PrettyFormat));
✅ 适用场景:动态生成 API 响应、配置模板构建、日志结构化输出。
✅ 6. 将 JavaBean 对象序列化为 JSON(补充说明)
本质与第4点相同,但强调JavaBean 规范的重要性:
// ✅ 正确:符合 JavaBean 规范
public class Order {
private Long id;
private String orderNo;
private Double amount;
public Order() {} // 必须有无参构造器
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getOrderNo() { return orderNo; }
public void setOrderNo(String orderNo) { this.orderNo = orderNo; }
public Double getAmount() { return amount; }
public void setAmount(Double amount) { this.amount = amount; }
}
// ✅ 序列化成功
Order order = new Order();
order.setId(1001L);
order.setOrderNo("ORD20251107");
order.setAmount(299.99);
String json = JSON.toJSONString(order);
// 输出:{"id":1001,"orderNo":"ORD20251107","amount":299.99}
// ❌ 错误:无无参构造器或字段无 getter
// 会导致序列化失败或字段丢失
✅ 建议:使用 Lombok
@Data注解自动生成 getter/setter/toString/构造器。
📌 三、FastJSON2 常用静态工具类详解
| 工具类 | 作用 | 使用场景 | 注意事项 |
|---|---|---|---|
JSON | 核心入口类,提供 parseObject, parseArray, toJSONString 等方法 | 所有 JSON 序列化/反序列化操作 | 最常用,推荐优先使用 |
JSONB | 二进制 JSON 格式工具类,支持高效序列化/反序列化 | 高性能场景(如缓存、RPC)、网络传输 | 比 JSON 字符串更小更快,但不可读 |
JSONPath | 类似 XPath 的 JSON 查询语言 | 从复杂 JSON 中提取部分字段,无需完整反序列化 | 性能高,适合大数据量筛选 |
SerializerFeature | 序列化选项枚举 | 控制输出格式(如是否输出 null、是否格式化) | 需配合 toJSONString(obj, features) 使用 |
JSONReader.Feature | 反序列化选项枚举 | 控制解析行为(如忽略大小写、允许注释) | 避免因字段名大小写导致解析失败 |
TypeReference<T> | 泛型类型引用 | 解析泛型集合(如 List<T>、Map<String, T>) | 必须使用匿名内部类,否则泛型擦除 |
示例:使用 SerializerFeature
String json = JSON.toJSONString(person,
SerializerFeature.WriteMapNullValue, // 输出 null 字段
SerializerFeature.WriteNullStringAsEmpty, // null 字符串转为 ""
SerializerFeature.WriteNullListAsEmpty, // null List 转为 []
SerializerFeature.PrettyFormat // 格式化输出
);
示例:使用 JSONReader.Feature
String json = "{\"Name\":\"张三\",\"AGE\":25}"; // 字段名大小写不一致
Person p = JSON.parseObject(json, Person.class,
JSONReader.Feature.IgnoreCaseMatch); // 忽略大小写,可成功映射
📌 四、进阶使用:JSONB 与 JSONPath
✅ 1. 将 JavaBean 对象序列化为 JSONB(二进制格式)
Person person = new Person();
person.setName("李雷");
person.setAge(27);
person.setCity("深圳");
// 序列化为 JSONB(byte[])
byte[] jsonbBytes = JSONB.toBytes(person);
System.out.println("JSONB 字节数组长度:" + jsonbBytes.length); // 比 JSON 字符串短 30%~50%
✅ 优势:体积小、序列化/反序列化速度快,适合 Redis 缓存、gRPC、消息队列(如 Kafka)传输。
✅ 2. 将 JSONB 数据解析为 JavaBean
// 使用上面的 jsonbBytes
Person deserialized = JSONB.parseObject(jsonbBytes, Person.class);
System.out.println(deserialized.getName()); // 输出:李雷
System.out.println(deserialized.getAge()); // 输出:27
✅ 注意:JSONB 反序列化必须完全匹配类结构,不支持字段缺失自动忽略(除非配置
Feature.IgnoreNotMatch)。
✅ 3. 使用 JSONPath 读取部分数据(从 JSON 字符串)
String json = "{\"user\":{\"name\":\"张三\",\"profile\":{\"age\":28,\"email\":\"zhangsan@xxx.com\"}},\"orders\":[{\"id\":1,\"status\":\"paid\"},{\"id\":2,\"status\":\"pending\"}]}";
// 使用 JSONPath 提取嵌套字段
String name = JSONPath.read(json, "$.user.name").toString(); // "张三"
Integer age = JSONPath.read(json, "$.user.profile.age"); // 28
List<String> statuses = JSONPath.read(json, "$.orders[*].status"); // ["paid", "pending"]
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("订单状态:" + statuses);
✅ JSONPath 语法参考:
$:根对象.:子对象[*]:数组所有元素[0]:数组第一个元素?():过滤条件(如$..orders[?(@.status=='paid')])
✅ 4. 使用 JSONPath 读取部分 byte[] 数据(JSONB)
byte[] jsonbBytes = JSONB.toBytes(person);
// 直接从 JSONB 字节数组中提取字段(无需反序列化整个对象)
String name = JSONPath.read(jsonbBytes, "$.name"); // "李雷"
Integer age = JSONPath.read(jsonbBytes, "$.age"); // 27
System.out.println("通过 JSONPath 从 JSONB 中提取:" + name + ", " + age);
✅ 优势:极大提升性能,适用于大对象中仅取少量字段的场景(如日志审计、监控指标提取)。
✅ 5. 使用 JSONPath 读取部分 byte[] 数据(再次强调)
此条与第4条相同,为强调其重要性,此处再给出一个实际业务场景:
// 业务场景:Redis 缓存了 1000 个用户信息(JSONB 格式),每次只取用户昵称和头像
String cacheKey = "user:1001";
byte[] cachedBytes = redisTemplate.opsForValue().get(cacheKey); // 从 Redis 获取 byte[]
// 只提取需要的字段,避免反序列化整个对象
String nickName = JSONPath.read(cachedBytes, "$.nickName");
String avatarUrl = JSONPath.read(cachedBytes, "$.avatarUrl");
// 仅构建一个轻量 DTO 返回
UserSummary summary = new UserSummary(nickName, avatarUrl);
⚡ 性能提升:反序列化 10KB 对象 vs. 仅解析 50 字节字段,性能差 10 倍以上。
📌 五、使用建议与推荐做法规则(必读!)
| 类别 | 推荐做法 | 说明 |
|---|---|---|
| ✅ 序列化/反序列化 | 优先使用 JSON 类的 toJSONString() 和 parseObject() | 简洁、安全、类型安全 |
| ✅ 泛型处理 | 使用 TypeReference<T> 处理 List<T>、Map<K,V> | 避免泛型擦除导致 LinkedHashMap 替代 |
| ✅ 字段映射 | JavaBean 字段命名使用 camelCase,与 JSON 保持一致 | 避免配置 @JSONField(name="xxx"),减少冗余 |
| ✅ 性能优化 | 高频场景(如缓存、RPC)使用 JSONB | 比 JSON 字符串节省 40% 内存,快 3~5 倍 |
| ✅ 数据提取 | 复杂 JSON 结构中只取部分字段 → 使用 JSONPath | 避免反序列化大对象,降低 GC 压力 |
| ✅ 安全防护 | 禁止使用 JSON.parse() 解析不可信输入 | 防止反序列化漏洞(如 JNDI 注入)→ 改用 JSON.parseObject(json, TargetClass.class) |
| ✅ 空值处理 | 在全局配置中统一设置 WriteMapNullValue, WriteNullStringAsEmpty | 避免前端因 null 值报错 |
| ✅ 日期格式 | 使用 @JSONField(format="yyyy-MM-dd HH:mm:ss") | 避免默认时间戳格式(Long)不兼容前端 |
| ✅ Spring Boot 集成 | 若使用 FastJSON2,显式替换默认 Jackson | 避免两库共存导致冲突或性能下降 |
| ✅ 日志打印 | 使用 JSON.toJSONString(obj, SerializerFeature.PrettyFormat) | 便于调试,但生产环境关闭,避免性能损耗 |
| ✅ 版本管理 | 始终使用 最新稳定版(如 2.0.54+) | FastJSON2 已修复所有历史安全漏洞 |
✅ 附:FastJSON2 安全性提醒(重要!)
⚠️ FastJSON1 曾有严重反序列化漏洞(CVE-2020-8840 等),但 FastJSON2 已彻底重构,不再支持 auto-type,默认安全!
// ✅ 安全写法(推荐)
Person p = JSON.parseObject(json, Person.class);
// ❌ 危险写法(FastJSON1 时代,FastJSON2 已禁用)
Object obj = JSON.parse(json); // 不指定类型,可能被利用
✅ 结论:只要不使用
JSON.parse()而是使用JSON.parseObject(json, YourClass.class),FastJSON2 是安全的。
✅ 总结:FastJSON2 使用决策树
你是否需要高性能、低内存?
├── 是 → 使用 JSONB(byte[]) + JSONPath 提取字段
└── 否 → 使用 JSON 字符串
你是否需要处理泛型集合?
├── 是 → 使用 TypeReference<List<T>>
└── 否 → 直接用 Class.class
你是否从外部接收不可信 JSON?
├── 是 → 必须指定目标类,禁用 auto-type
└── 否 → 可自由使用
你是否在 Spring Boot 中?
├── 是 → 显式配置 FastJSON2HttpMessageConverter 替换 Jackson
└── 否 → 直接使用 JSON 工具类即可
📚 推荐学习资源
- 官方文档:https://github.com/alibaba/fastjson2
- GitHub 示例:https://github.com/alibaba/fastjson2/tree/master/src/test/java/com/alibaba/fastjson2
- FastJSON2 vs Jackson 性能对比:https://github.com/alibaba/fastjson2/wiki/benchmark
✅ 最后建议:团队落地策略
| 目标 | 建议 |
|---|---|
| 统一 JSON 库 | 全团队使用 FastJSON2,替换 Jackson(尤其在高并发保险系统) |
| 代码规范 | 在代码规范文档中强制要求:JSON.parseObject(json, Class.class),禁止 JSON.parse() |
| 单元测试 | 使用 assertThat(json).isEqualTo(JSON.toJSONString(obj)) 验证序列化一致性 |
| 监控 | 在接口响应中添加 Content-Length 监控,观察 JSONB 是否降低带宽 |
| 培训 | 组织一次“FastJSON2 实战工作坊”,重点讲解 JSONPath 与 JSONB 缓存优化 |
💡 总结一句话:
FastJSON2 是高性能、安全、易用的 JSON 处理利器,尤其适合银行/保险等高并发、低延迟场景。善用 JSONB + JSONPath,可显著提升系统吞吐量与资源利用率。
5万+

被折叠的 条评论
为什么被折叠?



