Fastjson2 序列化过滤器
什么是序列化过滤器?
在日常的 Java 开发中,我们经常需要将对象转换成 JSON 字符串(序列化),或者从 JSON 字符串还原成对象(反序列化)。Fastjson2 是阿里巴巴开源的高性能 JSON 库,它提供了一个非常实用的功能——序列化过滤器,允许我们在序列化过程中动态控制哪些字段需要输出、如何输出。
序列化过滤器,简单来说就是个中间环节:对象要转成JSON的时候,它会决定哪些字段留下、哪些去掉,或者怎么改个样子再出去。
为什么需要过滤器?
假设你有一个用户对象,包含密码、身份证号等敏感信息。直接序列化整个对象可能导致数据泄露。或者你需要在特定场景下只输出部分字段(比如列表页只需要用户名和头像)。传统做法是创建多个 DTO(数据传输对象),但代码会变得冗余。Fastjson2 的过滤器可以优雅地解决这类问题。
核心 API 介绍
Fastjson2 提供了 Filter 接口及其子接口:
PropertyFilter:决定属性是否输出NameFilter:修改属性名ValueFilter:修改属性值BeforeFilter:在序列化某个对象前执行自定义操作AfterFilter:在序列化某个对象后执行自定义操作
最常用的是 PropertyFilter 和 ValueFilter。
实战例子
1. 创建示例对象
public class User {
private String username;
private String password;
private int age;
private String idCard;
private int score;
private int status;
}
2. 使用 PropertyFilter 排除字段
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.PropertyFilter;
public class FilterDemo {
public static void main(String[] args) {
User user = new User();
user.setUsername("小明");
user.setPassword("123456");
user.setAge(25);
user.setIdCard("110101199001011234");
// 只输出非敏感字段
PropertyFilter filter = (object, name, value) -> {
// 排除密码和身份证号
return !"password".equals(name) && !"idCard".equals(name);
};
String json = JSON.toJSONString(user, filter);
System.out.println(json);
// 输出:{"age":25,"username":"小明"}
}
}
3. 使用 ValueFilter 修改值
想要在序列化时对值做处理(比如脱敏),可以使用 ValueFilter:
import com.alibaba.fastjson2.filter.ValueFilter;
ValueFilter valueFilter = (object, name, value) -> {
if ("password".equals(name)) {
return "******"; // 密码脱敏
}
if ("idCard".equals(name)) {
String str = (String) value;
return str.substring(0, 6) + "********" + str.substring(14);
}
return value; // 其他字段不变
};
String json = JSON.toJSONString(user, valueFilter);
System.out.println(json);
// 输出:{"age":25,"idCard":"110101********1234","password":"******","username":"小明"}
4. 组合使用多个过滤器
Fastjson2 支持同时应用多个过滤器,按照添加顺序执行:
import com.alibaba.fastjson2.filter.Filter;
// 先过滤字段,再脱敏
Filter combinedFilter = FilterUtils.combine(filter, valueFilter);
// 或者直接传数组
String json = JSON.toJSONString(user, new Filter[]{filter, valueFilter});
高级用法:BeforeFilter 动态增加字段
有时需要在序列化时额外添加一些计算出的字段:
import com.alibaba.fastjson2.filter.BeforeFilter;
BeforeFilter beforeFilter = new BeforeFilter() {
@Override
public void writeBefore(Object object) {
User user = (User) object;
// 动态添加一个字段 "userType": "VIP"
writeKeyValue("userType", user.getAge() > 18 ? "VIP" : "普通");
}
};
String json = JSON.toJSONString(user, beforeFilter);
// 输出 {"userType":"VIP","age":25,"idCard":"110101199001011234","password":"123456","username":"小明"}
相应的AfterFilter例子:
import com.alibaba.fastjson2.filter.AfterFilter;
AfterFilter afterFilter = new AfterFilter() {
@Override
public void writeAfter(Object object) {
User user = (User) object;
// 在序列化完成后动态添加字段
writeKeyValue("userLevel", user.getScore() > 100 ? "黄金会员" : "普通会员");
writeKeyValue("isActive", user.getStatus() == 1);
}
};
String json = JSON.toJSONString(user, afterFilter);
// 输出 {"age":25,"idCard":"110101199001011234","password":"123456","username":"小明","userLevel":"普通会员","isActive":true}
实际应用场景
- 接口数据裁剪:不同 API 返回不同字段集,减少网络传输量
- 敏感信息脱敏:密码、身份证号、手机号等在日志或非安全环境中脱敏
- 字段重命名:将 Java 的驼峰命名转为下划线命名(
NameFilter实现) - 日志过滤:避免打印过大的二进制数据或敏感信息
小结
Fastjson2 的序列化过滤器提供了灵活、优雅的方式来控制 JSON 输出。相比创建多个 DTO 类,过滤器方式代码更简洁,维护更方便。

