序列化 之 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 工作流程(简化)
- 序列化:
- 通过反射获取对象字段;
- 调用内置或自定义
ObjectSerializer; - 输出为字符串或写入
Writer/OutputStream。
- 反序列化:
- 解析 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。
✅ 最佳实践
- 使用
TypeReference处理泛型。 - 敏感字段用
@JSONField(serialize = false)。 - 日期统一用
@JSONField(format = "...")。 - 生产环境关闭
WriteClassName。 - 升级到 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 清晰、安全性提升。
- 核心类:
JSON、JSONObject、JSONArray。 - 通过
@JSONField和Feature精细控制序列化行为。 - 安全第一:禁用 autoType,避免反序列化攻击。
- 自定义逻辑可通过
ObjectWriter/ObjectReader实现。
📌 虽然 Fastjson 仍有使用场景,但在新项目中,若无特殊性能要求,Jackson(Spring Boot 默认)仍是更安全、标准的选择。
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/19523195

浙公网安备 33010602011771号