序列化 之 fastJson(一)概要

Fastjson 是阿里巴巴开源的一款高性能 Java JSON 库,广泛用于 Java 应用中进行 JSON 序列化(Java → JSON)反序列化(JSON → Java)。虽然近年来因安全漏洞问题在部分场景被 Jackson 替代,但其简洁 API 和高性能仍使其在很多项目中使用。


一、Fastjson 核心原理

1.1 架构组成

  • JSON:核心工具类,提供 toJSONString()parseObject()parseArray() 等静态方法。
  • JSONObject / JSONArray:动态 JSON 对象/数组表示,类似 Map/List。
  • SerializerFeature / Feature:控制序列化/反序列化行为的配置项。
  • ObjectSerializer / ObjectDeserializer:自定义序列化/反序列化逻辑接口。
  • ASM + 反射优化:Fastjson 内部大量使用字节码生成(ASM)和缓存反射信息,提升性能。

1.2 工作流程(简化)

  1. 序列化
    • 通过反射获取对象字段;
    • 调用内置或自定义 ObjectSerializer
    • 输出为字符串或写入 Writer/OutputStream
  2. 反序列化
    • 解析 JSON 字符串为 Token 流;
    • 根据目标类型(Class)创建实例;
    • 通过 setter 或字段直接赋值(支持私有字段);
    • 支持自动类型推断(需谨慎,有安全风险)。

⚠️ 注意:Fastjson 的 autoType 功能(自动识别 @type 字段)曾多次爆出 远程代码执行(RCE)漏洞,生产环境务必关闭或严格白名单控制。


二、Maven 依赖(推荐使用最新安全版本)

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.57</version> <!-- Fastjson 2.x 是重构版,更安全 -->
</dependency>

强烈建议使用 Fastjson 2.x(包名 com.alibaba.fastjson2,1.x 已停止维护且存在高危漏洞。

本文以 Fastjson 2.x 为主(API 更清晰、安全性更高),同时标注 1.x 差异。


三、基础使用示例(Fastjson 2.x)

3.1 引入包(注意包名变化)

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.JSONReader;

Fastjson 1.x 包名是 com.alibaba.fastjson


3.2 Java 对象 → JSON 字符串(序列化)

public class User {
    public String name;
    public int age;
    public Date createTime;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
        this.createTime = new Date();
    }
}

// 序列化
User user = new User("张三", 25);
String json = JSON.toJSONString(user);
System.out.println(json);
// 输出: {"age":25,"createTime":1706000000000,"name":"张三"}

格式化输出(Pretty)

String prettyJson = JSON.toJSONString(user, JSONWriter.Feature.PrettyFormat);

忽略 null 值

String json = JSON.toJSONString(user, JSONWriter.Feature.WriteNulls); // 默认不写 null
// 若想忽略 null:
String json = JSON.toJSONString(user, JSONWriter.Feature.NotWriteDefaultValue);

3.3 JSON 字符串 → Java 对象(反序列化)

String json = "{\"name\":\"李四\",\"age\":30}";
User user = JSON.parseObject(json, User.class);
System.out.println(user.name); // 李四

泛型支持(List、Map)

String jsonArray = "[{\"name\":\"A\",\"age\":1},{\"name\":\"B\",\"age\":2}]";

// 方式1:TypeReference(推荐)
List<User> users = JSON.parseObject(jsonArray, 
    new TypeReference<List<User>>() {});

// 方式2:直接 Class(仅限非泛型)
JSONArray array = JSON.parseArray(jsonArray);
User first = array.get(0).to(User.class);

3.4 动态 JSON 操作(JSONObject / JSONArray)

// 创建 JSONObject
JSONObject obj = new JSONObject();
obj.put("name", "王五");
obj.put("score", 95);

// 获取值
String name = obj.getString("name");
int score = obj.getIntValue("score");

// 转为 Java 对象
User user = obj.to(User.class);

// JSONArray
JSONArray arr = new JSONArray();
arr.add(obj);
arr.add(new JSONObject(Map.of("name", "赵六")));

// 遍历
for (Object o : arr) {
    JSONObject item = (JSONObject) o;
    System.out.println(item.getString("name"));
}

四、常用配置选项(Feature)

4.1 序列化配置(JSONWriter.Feature)

配置项 说明
WriteNulls 输出 null 字段(默认不输出)
PrettyFormat 格式化输出(缩进)
WriteClassName 写入 @type 字段(危险!慎用)
FieldBased 使用字段而非 getter(可访问私有字段)
NotWriteDefaultValue 不输出默认值(如 0、false、null)

示例:

JSON.toJSONString(user, 
    JSONWriter.Feature.PrettyFormat,
    JSONWriter.Feature.WriteNulls
);

4.2 反序列化配置(JSONReader.Feature)

配置项 说明
SupportAutoType 启用 @type 自动类型(高危!默认关闭)
UseNativeObject 使用 JSONObject/JSONArray 而非 Map/List
IgnoreSetNullValue 忽略 JSON 中的 null 值(不调用 setter)

🔒 安全建议:永远不要开启 SupportAutoType,除非你明确知道风险并配置了白名单。


五、注解控制序列化行为

Fastjson 提供丰富注解:

注解 作用
@JSONField(name = "userName") 自定义字段名
@JSONField(serialize = false) 序列化时忽略
@JSONField(deserialize = false) 反序列化时忽略
@JSONField(format = "yyyy-MM-dd") 日期格式化
@JSONField(ordinal = 1) 控制字段顺序

示例:

public class User {
    @JSONField(name = "full_name")
    public String name;

    @JSONField(serialize = false)
    public String password;

    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    public Date loginTime;
}

六、自定义序列化/反序列化

6.1 实现 ObjectWriter(序列化)

public class PhoneWriter implements ObjectWriter<String> {
    @Override
    public void write(JSONWriter writer, Object object, Object fieldName, Type fieldType, long features) {
        String phone = (String) object;
        if (phone != null && phone.length() == 11) {
            String masked = phone.substring(0, 3) + "****" + phone.substring(7);
            writer.writeString(masked);
        } else {
            writer.writeString(phone);
        }
    }
}

注册方式(全局):

// Fastjson 2.x 暂不支持简单全局注册,通常用注解
@JSONField(serializeUsing = PhoneWriter.class)
public String phone;

6.2 实现 ObjectReader(反序列化)

public class EncryptedPhoneReader implements ObjectReader<String> {
    @Override
    public String readObject(JSONReader reader, Type fieldType, Object fieldName, long features) {
        String encrypted = reader.readString();
        // 模拟解密
        return decrypt(encrypted);
    }
}

使用:

@JSONField(deserializeUsing = EncryptedPhoneReader.class)
public String phone;

七、Fastjson 1.x vs 2.x 主要区别

特性 Fastjson 1.x Fastjson 2.x
包名 com.alibaba.fastjson com.alibaba.fastjson2
性能 更快(重构优化)
安全性 多次高危漏洞 默认禁用 autoType,更安全
API SerializerFeature JSONWriter.Feature
注解 @JSONField 相同 兼容,新增功能
Android 支持 支持 更好支持

新项目请优先使用 Fastjson 2.x


八、常见问题与最佳实践

❌ 安全问题

  • 永远不要开启 SupportAutoType,除非配合白名单:
    ParserConfig.getGlobalInstance().addAccept("com.yourpackage.");
    
  • 避免反序列化不可信来源的 JSON。

✅ 最佳实践

  1. 使用 TypeReference 处理泛型。
  2. 敏感字段用 @JSONField(serialize = false)
  3. 日期统一用 @JSONField(format = "...")
  4. 生产环境关闭 WriteClassName
  5. 升级到 Fastjson 2.x。

九、完整示例(Fastjson 2.x)

import com.alibaba.fastjson2.*;

import java.util.*;

public class FastjsonDemo {
    public static void main(String[] args) {
        // 1. 序列化
        User user = new User("Alice", 28);
        String json = JSON.toJSONString(user, JSONWriter.Feature.PrettyFormat);
        System.out.println(json);

        // 2. 反序列化
        User parsed = JSON.parseObject(json, User.class);

        // 3. 泛型 List
        List<User> users = Arrays.asList(user, new User("Bob", 30));
        String listJson = JSON.toJSONString(users);
        List<User> parsedList = JSON.parseObject(listJson, 
            new TypeReference<List<User>>() {});

        // 4. 动态操作
        JSONObject obj = JSON.parseObject(json);
        obj.put("extra", "info");
        System.out.println(obj.getString("name"));
    }

    public static class User {
        @JSONField(name = "user_name")
        public String name;
        public int age;
        @JSONField(format = "yyyy-MM-dd HH:mm:ss")
        public Date createTime;

        public User(String name, int age) {
            this.name = name;
            this.age = age;
            this.createTime = new Date();
        }
    }
}

总结

  • Fastjson 2.x 是目前推荐版本,性能高、API 清晰、安全性提升。
  • 核心类:JSONJSONObjectJSONArray
  • 通过 @JSONFieldFeature 精细控制序列化行为。
  • 安全第一:禁用 autoType,避免反序列化攻击。
  • 自定义逻辑可通过 ObjectWriter/ObjectReader 实现。

📌 虽然 Fastjson 仍有使用场景,但在新项目中,若无特殊性能要求,Jackson(Spring Boot 默认)仍是更安全、标准的选择

posted @ 2026-01-23 16:53  蓝迷梦  阅读(4)  评论(0)    收藏  举报