Fastjson2 全面使用指南(Java后端开发者专用)

一、Fastjson2 简介

Fastjson2 是阿里巴巴开源的高性能 JSON 处理库,是 fastjson 1.x 的升级版。相比旧版本,它在性能、安全性、功能扩展上均有显著提升:

  • 支持 JSONB 二进制格式(比文本 JSON 更高效)
  • 内置 JSONPath 查询引擎
  • 严格的安全机制(默认禁用 AutoType)
  • 兼容 Jackson/Spring 的注解规范
  • 支持流式处理超大 JSON 数据

📌 依赖配置(Maven):

<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.40</version>
</dependency>

二、基础使用场景详解

1. 将 JSON 解析为 JSONObject

import com.alibaba.fastjson2.JSONObject;

String jsonStr = "{\"name\":\"张三\", \"age\":30, \"isStudent\":false}";
// 解析 JSON 字符串为 JSONObject
JSONObject obj = JSON.parseObject(jsonStr);

// 获取字段值(自动类型转换)
String name = obj.getString("name"); // "张三"
int age = obj.getIntValue("age");    // 30
boolean isStudent = obj.getBoolean("isStudent"); // false

// 遍历所有字段
obj.forEach((key, value) -> {
    System.out.println(key + " => " + value);
});

2. 将 JSON 解析为 JSONArray

import com.alibaba.fastjson2.JSONArray;

String jsonArrayStr = "[\"苹果\", {\"id\":1, \"name\":\"香蕉\"}, 3.14]";
// 解析为 JSONArray
JSONArray array = JSON.parseArray(jsonArrayStr);

// 获取第一个元素(字符串)
String first = array.getString(0); // "苹果"

// 获取第二个元素(JSONObject)
JSONObject fruit = array.getJSONObject(1);
String fruitName = fruit.getString("name"); // "香蕉"

// 遍历数组
for (int i = 0; i < array.size(); i++) {
    System.out.println("第 " + i + " 项: " + array.get(i));
}

3. 将 JSON 解析为 Java 对象

import com.alibaba.fastjson2.JSON;

// 定义 JavaBean
public class User {
    private String name;
    private int age;
    private java.util.Date birthDate;
    
    // 必须有无参构造函数
    public User() {}
    // getter/setter...
}

String json = "{\"name\":\"李四\", \"age\":25, \"birthDate\":\"2000-01-01\"}";
// 直接解析为 User 对象
User user = JSON.parseObject(json, User.class);

// 自定义日期格式解析(通过 @JSONField 注解)
public class User {
    @JSONField(format = "yyyy-MM-dd") // 指定日期格式
    private java.util.Date birthDate;
    // ...
}

// 自动解析为 Date 对象
System.out.println(user.getBirthDate()); // 输出:Sat Jan 01 00:00:00 CST 2000

4. 将 Java 对象序列化为 JSON

User user = new User();
user.setName("王五");
user.setAge(30);

// 基础序列化
String jsonStr = JSON.toJSONString(user); 
// 输出: {"name":"王五","age":30}

// 格式化输出(带缩进)
String prettyJson = JSON.toJSONString(user, SerializerFeature.PrettyFormat);
// 输出:
// {
//   "name": "王五",
//   "age": 30
// }

// 排除 null 字段
String noNullJson = JSON.toJSONString(user, SerializerFeature.WriteMapNullValue);

5. 使用 JSONObjectJSONArray 动态操作数据

// 动态构建 JSON 对象
JSONObject obj = new JSONObject();
obj.put("name", "动态数据");
obj.put("score", 95.5);
obj.put("tags", new JSONArray(Arrays.asList("Java", "Spring")));

// 嵌套结构
JSONObject nested = new JSONObject();
nested.put("address", "北京");
obj.put("info", nested);

// 序列化为字符串
System.out.println(JSON.toJSONString(obj));
// 输出: {"name":"动态数据","score":95.5,"tags":["Java","Spring"],"info":{"address":"北京"}}

6. JavaBean 序列化为 JSON 的高级配置

// 自定义序列化选项
SerializerFeature[] features = {
    SerializerFeature.PrettyFormat, // 格式化
    SerializerFeature.WriteDateUseDateFormat, // 日期转字符串
    SerializerFeature.WriteNullStringAsEmpty // 空字符串转""
};

String customJson = JSON.toJSONString(user, features);

三、进阶使用场景

1. JSONB 二进制格式处理

// 序列化为 JSONB 二进制(更小体积、更快解析)
byte[] jsonbBytes = JSONB.toBytes(user);

// 反序列化 JSONB 数据
User user2 = JSONB.parseObject(jsonbBytes, User.class);

// JSONB 适合场景:
// - 服务间通信(如 RPC)
// - 缓存存储(Redis)
// - 大数据量传输

2. JSONPath 查询数据

String json = "{\"store\":{\"book\":[{\"title\":\"Java\"},{\"title\":\"Spring\"}]}}";

// 读取第一本书的标题
String title = JSONPath.read(json, "$.store.book[0].title").toString(); // "Java"

// 读取所有书名
List<String> titles = JSONPath.read(json, "$.store.book[*].title"); // ["Java", "Spring"]

// 修改数据
JSONPath.write(json, "$.store.book[0].title", "Java核心技术");
// 输出: {"store":{"book":[{"title":"Java核心技术"},...}}}

3. 处理 byte[] 类型的 JSONPath 查询

byte[] jsonbBytes = JSONB.toBytes("{\"name\":\"张三\",\"age\":30}");

// 直接对 byte[] 使用 JSONPath 查询
Object age = JSONPath.read(jsonbBytes, "$.age"); // 30

// 注意:JSONPath 支持直接处理 JSONB 格式的 byte[]

四、常用静态工具类详解

工具类作用使用场景示例
JSON基础 JSON 处理核心类字符串 JSON 的序列化/反序列化JSON.parseObject(str, User.class)
JSONB二进制 JSON 格式处理高性能场景(服务通信、缓存)JSONB.toBytes(obj), JSONB.parseObject(bytes, Class)
JSONPathJSON 数据查询引擎从复杂 JSON 中提取部分数据JSONPath.read(json, "$.path")
JSONWriter流式 JSON 序列化处理超大 JSON 数据(避免内存溢出)JSONWriter.of(out).writeObject(obj)
JSONReader流式 JSON 反序列化读取大文件或网络流式数据JSONReader.of(in).readObject(User.class)
SerializerFeature序列化选项配置控制输出格式(日期、空值、缩进等)JSON.toJSONString(obj, SerializerFeature.PrettyFormat)
ParseFeature解析选项配置处理非标准 JSON(单引号、注释等)JSON.parseObject(str, ParseFeature.AllowSingleQuotes)
JSONReaderConfig反序列化全局配置安全控制(禁用 AutoType)new JSONReaderConfig().setSupportAutoType(false)
JSONWriterConfig序列化全局配置统一序列化行为new JSONWriterConfig().setDateFormat("yyyy-MM-dd")

五、最佳实践与安全建议

✅ 推荐做法

  1. 优先使用 JSONB 格式

    • 服务间通信、Redis 缓存等场景优先使用 JSONB,比文本 JSON 性能提升 30% 以上
    • 示例:byte[] data = JSONB.toBytes(obj);
  2. 严格禁用 AutoType

    // 安全配置:禁用自动类型识别(防止反序列化漏洞)
    JSONReaderConfig config = new JSONReaderConfig();
    config.setSupportAutoType(false);
    JSONReader reader = JSONReader.of(jsonStr, config);
    
  3. 使用 JSONPath 优化查询

    • 当只需要 JSON 中的少量数据时,避免完整解析整个 JSON
    • 示例:JSONPath.read(json, "$.data.list[0].id") 比解析整个对象更高效
  4. 流式处理超大 JSON

    // 从文件流中读取大 JSON(避免 OOM)
    try (InputStream in = new FileInputStream("large.json")) {
        JSONReader reader = JSONReader.of(in);
        List<User> users = reader.readArray(User.class);
    }
    
  5. 自定义日期格式

    // 全局配置日期格式(推荐)
    JSONWriterConfig config = new JSONWriterConfig();
    config.setDateFormat("yyyy-MM-dd HH:mm:ss");
    JSON.setWriterConfig(config);
    

⚠️ 安全红线

  • 禁止启用 SupportAutoType:除非明确使用白名单机制
  • 不要直接反序列化不可信数据:外部传入的 JSON 必须经过严格校验
  • 敏感字段脱敏:使用 @JSONField(serialize = false) 隐藏密码等字段

🔍 性能优化技巧

场景优化方案
高频序列化使用 JSONWriter 流式写入
重复解析相同 JSON缓存解析后的 JSONObject
大数组处理使用 JSONReader.readArray() 流式读取
日期处理全局配置 setDateFormat 避免重复创建格式化器

六、完整示例:安全高效的 JSON 处理

// 安全配置:禁用 AutoType + 自定义日期格式
JSONWriterConfig writerConfig = new JSONWriterConfig();
writerConfig.setDateFormat("yyyy-MM-dd");
JSON.setWriterConfig(writerConfig);

JSONReaderConfig readerConfig = new JSONReaderConfig();
readerConfig.setSupportAutoType(false); // 严格禁止自动类型识别

// 序列化对象(安全模式)
User user = new User("张三", 30, new Date());
byte[] jsonb = JSONB.toBytes(user); // 二进制格式

// 反序列化(安全模式)
try {
    User parsed = JSONB.parseObject(jsonb, User.class, readerConfig);
    System.out.println(parsed.getName()); // 安全解析
} catch (Exception e) {
    // 处理非法数据
}

💡 总结:Fastjson2 是当前 Java 生态中性能最优、安全性最高的 JSON 库。在 SpringCloud 微服务中推荐使用 JSONB 格式进行服务间通信,配合 JSONPath 实现高效数据查询,同时严格遵循安全配置规范。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龙茶清欢

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

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

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

打赏作者

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

抵扣说明:

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

余额充值