FastJSON2 完全使用指南(Java 后端开发实战版)

以下是一份系统性、综合性、全面的 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. 使用 JSONObjectJSONArray 动态构建与操作

// 动态构建 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,可显著提升系统吞吐量与资源利用率。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值