Fastjson2 版本演进

作为 Java 开发者,你一定对 Fastjson 不陌生。这个由阿里巴巴开源的 JSON 处理库,凭借其高性能和易用性,曾经是无数项目的标配。但随着时间的推移,Fastjson 1.x 版本也暴露了一些架构上的局限。于是,Fastjson2 应运而生。接下来介绍这个Fastjson版本演进。

为什么要有 Fastjson2?

Fastjson 1.x 的底层设计基于“将 JSON 字符串解析为内部中间表示(如 JSONObject/JSONArray)再处理”的模式,这在早期满足了大多数需求。但随着业务复杂度提升(如超大 JSON 的流式处理、安全漏洞修复等),1.x 的架构已难以优雅扩展。Fastjson2 从 2022 年起开始重构,目标是:兼容 1.x 的核心 API,同时引入更安全、更高效的底层实现

版本演进的关键变化

1. Maven坐标变化

这是最直观的变化。在 Maven 中引入依赖时,包名从 com.alibaba.fastjson 变成了 com.alibaba.fastjson2

<!-- Fastjson2 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.61</version> <!-- 请使用最新版本 -->
</dependency>

注意:如果你还在用 1.x,升级时需要修改导入语句和部分 API 调用方式。

2. 核心 API更一致的方法命名

Fastjson2 对方法命名做了统一,告别了 1.x 中 toJSONString()parseObject() 混用的混乱。现在主要使用:

  • JSON.toJSONString(Object) → 序列化
  • JSON.parseObject(String, Class<T>) → 反序列化到 Java 对象
  • JSON.parseArray(String, Class<T>) → 反序列化到 List

3. 默认禁用类型自动绑定

1.x 的一个臭名昭著的特性是默认开启 AutoType(自动类型绑定),这导致了严重的反序列化安全漏洞。Fastjson2 默认禁用它,并且提供了更安全的配置方式。

示例:安全解析

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.Filter;

public class SafeExample {
    public static void main(String[] args) {
        String json = "{\"name\":\"Alice\",\"age\":25}";

        // 默认安全,无需额外配置
        User user = JSON.parseObject(json, User.class);
        System.out.println(user.getName()); // 输出: Alice
    }
}

class User {
    private String name;
    private int age;
    // getter/setter 略
}

Fastjson从 1.x 迁移到 2.x

假设你的旧项目中有这样一段 1.x 代码:

// Fastjson 1.x 写法
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

JSONObject obj = JSON.parseObject("{\"key\":\"value\"}");
String value = obj.getString("key");

在 Fastjson2 中,可以等价替换为:

// Fastjson2 写法
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

JSONObject obj = JSON.parseObject("{\"key\":\"value\"}");
String value = obj.getString("key");

注意JSONObject 类名相同,但包路径不同。如果你使用 IDE 的自动导入,注意选择 com.alibaba.fastjson2 包下的类。

更常见的场景:直接转为 POJO

推荐的做法是使用强类型的 POJO 而非 JSONObject

String json = """
    {"id":1,"name":"Fastjson2","version":"2.0.0"}
    """;

// 反序列化到 POJO
Library lib = JSON.parseObject(json, Library.class);
System.out.println(lib.getName()); // Fastjson2

// 序列化回 JSON
String out = JSON.toJSONString(lib);
System.out.println(out); // {"id":1,"name":"Fastjson2","version":"2.0.0"}

高级特性:流式读取大文件

Fastjson2 引入了一个新的特性:流式 API。它允许你以流的形式逐个读取 JSON 数组中的元素,避免一次性加载整个 JSON 到内存。

import com.alibaba.fastjson2.JSONReader;

try (JSONReader reader = JSONReader.of(new FileReader("large.json"))) {
    reader.startArray();
    while (reader.hasNext()) {
        User user = reader.read(User.class);
        // 处理每个 user
    }
    reader.endArray();
}

上面的例子中,用于逐个读取超大 JSON 数组中的元素,避免一次性加载整个数组到内存。

核心流程:

  1. JSONReader.of() 创建流式读取器
  2. startArray() 定位到数组开头
  3. hasNext() + read(User.class) 循环读取每个元素(一次只解析一个对象)
  4. endArray() 结束解析

与传统方式对比:

  • 传统:JSON.parseArray() → 一次性加载全部 → 大文件易 OOM
  • 流式:逐个读取 → 内存只占一个对象 → 适合超大 JSON

总结

Fastjson2 不是对 1.x 的简单修补,而是一次彻底的架构升级。它继承了 1.x 的高性能优点,同时弥补了安全性、可扩展性上的短板。对于新项目,强烈建议直接使用 Fastjson2;对于旧项目,Fastjson 2.x 也提供了兼容模块(fastjson2-extension),让你平滑迁移。

版本演进的本质是技术对现实需求的回应。从 1.x 到 2.x,Fastjson 学会了在“快”与“安全”之间找到更好的平衡。