以下是一份企业级 Java 后端开发中 FastJson2 的标准使用指南,按操作类型进行系统化分类,涵盖最推荐、最安全、最高效的使用方式,每个示例均附详细中文注释,并结合真实业务场景设计,助力团队统一规范、安全落地。
📚 FastJson2 标准使用指南(企业级 Java 后端开发规范版)
适用场景:Spring Boot 微服务、REST API、Redis 缓存、消息队列、配置中心、日志系统
核心原则:安全第一、性能优先、规范统一、可维护性强
版本要求:FastJson2 2.0.54+,JDK 11+(推荐 JDK 17 或 21)
依赖:<dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.54</version> </dependency> <!-- 如果项目使用SpringFramework等框架,可以使用fastjson-extension模块,使用方式参考 [SpringFramework Support] --> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2-extension-spring6</artifactId> <version>2.0.54</version> </dependency>
✅ 一、基础序列化与反序列化(最常用场景)
1.1 序列化单个 POJO 对象为 JSON 字符串(API 响应标准写法)
import com.alibaba.fastjson2.JSON;
import java.time.LocalDateTime;
import lombok.*;
// 实体类:用户信息(生产环境必须有无参构造)
@Data
public class User {
private Long id;
private String name;
private String email;
private LocalDateTime createTime;
}
// 【标准写法】序列化用户对象为 JSON 字符串(API 响应)
public class StandardSerializeDemo {
public static void main(String[] args) {
// 创建用户对象
User user = new User(1001L, "李明", "liming@company.com", LocalDateTime.now());
// ✅ 推荐:使用 JSON.toJSONString() 序列化,自动格式化,可读性强
// 注意:默认不输出 null 字段,减少传输体积,符合 REST API 最佳实践
String json = JSON.toJSONString(user);
System.out.println("【标准序列化】用户对象转 JSON:");
System.out.println(json);
// 输出:{"id":1001,"name":"李明","email":"liming@company.com","createTime":"2025-10-15T11:00:00"}
// 可以使用 JSONWriter.Feature.PrettyFormat 指定序列化后的 JSON 字符串保持标准的美化格式
String result = JSON.toJSONString(user, JSONWriter.Feature.PrettyFormat);
// 基础序列化 - 对象转JSON字符串
String jsonString = JSON.toJSONString(user);
System.out.println("基础序列化: " + jsonString);
// 美化格式输出
String prettyJson = JSON.toJSONString(user, JSONWriter.Feature.PrettyFormat);
System.out.println("美化格式: \n" + prettyJson);
// FastJson2 序列化时默认忽略所有 null 值的字段
user.setAge(null);
String ignoreNullJson = JSON.toJSONString(user,
JSONWriter.Feature.WriteNulls, // 通过手动设置该配置来包含null值
JSONWriter.Feature.PrettyFormat);
System.out.println("包含null值: \n" + ignoreNullJson);
// ✅ 企业建议:在 Controller 中直接返回 User 对象,由 Spring Boot 自动序列化(见下方 Spring 集成建议)
}
}
✅ 注释说明:
JSON.toJSONString(obj)是最安全、最推荐的序列化方式,内部自动启用写入优化。- 禁止使用
JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue)等非标准配置,除非业务明确要求。- 默认日期格式为 ISO-8601(
2025-10-15T11:00:00),前端可直接解析,无需额外转换。
1.2 反序列化 JSON 字符串为 POJO 对象(API 请求解析标准写法)
import com.alibaba.fastjson2.JSON;
// 【标准写法】从 JSON 字符串还原为 User 对象(接收前端请求)
public class StandardDeserializeDemo {
public static void main(String[] args) {
// 模拟从前端或 HTTP 请求接收到的 JSON 字符串
String json = "{\"id\":1001,\"name\":\"李明\",\"email\":\"liming@company.com\",\"createTime\":\"2025-10-15T11:00:00\"}";
// ✅ 推荐:使用 JSON.parseObject(json, TargetClass.class)
// 1. 类型安全:编译期校验,避免运行时 ClassCastException
// 2. 安全性高:FastJSON2 不会自动加载任意类(无 autoType 默认开启)
// 3. 性能最优:内部使用缓存的 ClassReader,避免重复反射
User user = JSON.parseObject(json, User.class);
System.out.println("【标准反序列化】JSON 转 User 对象:");
System.out.println("ID: " + user.getId());
System.out.println("姓名: " + user.getName());
System.out.println("邮箱: " + user.getEmail());
System.out.println("创建时间: " + user.getCreateTime());
// ✅ 企业建议:在 Controller 的 @RequestBody 参数中直接使用 User 类型,Spring Boot 会自动调用此方法
}
}
✅ 注释说明:
- 绝对禁止使用
JSON.parseObject(json, Object.class)—— 会导致类型擦除,无法校验结构,是安全漏洞根源。- 禁止使用
JSON.parse(json)返回JSONObject—— 丢失类型信息,不利于代码维护。- 必须指定目标类型(
User.class),这是 FastJson2 安全机制的核心。
1.3 序列化/反序列化 List 集合(批量数据传输)
import com.alibaba.fastjson2.JSON;
import java.util.List;
import java.util.Arrays;
// 【标准写法】序列化用户列表(如分页查询结果)
public class ListSerializeDemo {
public static void main(String[] args) {
List<User> userList = Arrays.asList(
new User(1001L, "张三", "zhangsan@company.com", LocalDateTime.now()),
new User(1002L, "李四", "lisi@company.com", LocalDateTime.now())
);
// ✅ 推荐:直接序列化 List,FastJSON2 自动识别泛型结构
String json = JSON.toJSONString(userList);
System.out.println("【标准序列化】用户列表转 JSON:");
System.out.println(json);
// 输出:[{"id":1001,"name":"张三","email":"zhangsan@company.com","createTime":"2025-10-15T11:00:00"}, ...]
// ✅ 推荐:反序列化为 List<User>,使用 JSON.parseArray(json, TargetClass.class) 指定目标类型
List<User> parsedList = JSON.parseArray(json, User.class);
System.out.println("\n【标准反序列化】JSON 转用户列表:");
System.out.println("总人数:" + parsedList.size());
parsedList.forEach(u -> System.out.println("用户:" + u.getName()));
}
}
✅ 二、字段级控制(注解驱动,企业级核心规范)
2.1 使用 @JSONField 控制字段序列化行为
import com.alibaba.fastjson2.annotation.JSONField;
import java.math.BigDecimal;
import java.time.LocalDateTime;
// 【标准实体类】订单信息(含敏感字段、格式化字段)
@Data
public class Order {
@JSONField(name = "order_id", serialize = true, deserialize = true)
private Long orderId;
@JSONField(name = "total_amount", serialize = true, deserialize = true, format = "###,##0.00")
private BigDecimal totalAmount;
@JSONField(name = "create_time", serialize = true, deserialize = true, format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@JSONField(name = "customer_phone", serialize = true, deserialize = true, serializeFeatures = JSONField.Feature.WriteNullStringAsEmpty)
private String customerPhone; // 电话号码,空值输出为 "" 而非 null
@JSONField(serialize = false) // ✅ 生产环境必须禁用序列化
private String internalRemark; // 内部备注,仅后端使用,禁止暴露给前端
@JSONField(serialize = false, deserialize = false) // ✅ 安全红线:完全忽略
private String password; // 密码字段,绝对禁止传输
@JSONField(serialize = false) // ✅ 非持久化字段,仅用于计算
private String displayStatus; // 显示状态:已支付、待发货
}
// 【标准使用】序列化订单对象
public class JSONFieldDemo {
public static void main(String[] args) {
Order order = new Order(
5001L,
new BigDecimal("12345.678"),
LocalDateTime.of(2025, 10, 15, 11, 30, 0),
"13800138000",
"内部:VIP客户,需优先发货",
"hashed_password_12345"
);
// ✅ 序列化结果将自动应用注解配置
String json = JSON.toJSONString(order);
System.out.println("【@JSONField 标准输出】:");
System.out.println(json);
// 输出:
// {
// "order_id": 5001,
// "total_amount": "12,345.68", // 格式化金额(保留两位小数)
// "create_time": "2025-10-15 11:30:00", // 自定义日期格式
// "customer_phone": "13800138000", // 电话号码正常输出
// "displayStatus": "已支付" // 注意:此字段未被序列化!因为 serialize=false
// }
// ✅ 注意:internalRemark 和 password 完全不出现在 JSON 中!
// 这是企业级安全规范的核心体现!
}
}
✅ 注释说明:
name:强制统一字段命名规范(如 snake_case),适配前端或第三方系统。format:日期与数字格式必须显式定义,避免跨系统解析错误。serialize = false:所有敏感字段(密码、token、内部ID)必须禁用序列化。deserialize = false:仅用于防止客户端伪造字段注入(如恶意传入 password)。serializeFeatures = WriteNullStringAsEmpty:推荐用于字符串字段,避免前端处理 null 逻辑。
2.2 使用 @JSONType 控制类级行为
import com.alibaba.fastjson2.annotation.JSONType;
// 【标准类】配置类:系统参数
@JSONType(
orders = {"paramName", "paramValue", "description"}, // ✅ 指定字段输出顺序(提升可读性)
ignoreCase = true, // ✅ 忽略字段名大小写(兼容旧系统)
serializeFeatures = JSONType.Feature.WriteMapNullValue // ✅ 允许输出 null(仅配置类适用)
)
@Data
public class SystemConfig {
private String paramName;
private String paramValue;
private String description;
}
// 【使用示例】
public class JSONTypeDemo {
public static void main(String[] args) {
SystemConfig config = new SystemConfig("cache.expire", "3600", "缓存过期时间(秒)");
String json = JSON.toJSONString(config);
System.out.println("【@JSONType 输出】:");
System.out.println(json);
// 输出:{"paramName":"cache.expire","paramValue":"3600","description":"缓存过期时间(秒)"}
// 字段顺序严格按 orders 定义,提升可读性
}
}
✅ 注释说明:
orders:强烈推荐用于配置类、日志类、审计类,保证输出顺序一致,便于 diff 比较。ignoreCase = true:兼容非标准前端传参(如传UserName或username)。- 不推荐在普通实体类中使用,避免耦合序列化逻辑。
✅ 三、高级功能(企业级场景专用)
3.1 自定义日期格式化(全局统一标准)
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import java.time.LocalDateTime;
// 【标准做法】在应用启动时设置全局日期格式(推荐写在 @Configuration 类中)
public class GlobalDateFormatConfig {
public static void init() {
// ✅ 推荐:全局统一使用 "yyyy-MM-dd HH:mm:ss" 格式
// 原因:前端 JS 的 Date.parse() 在解析 ISO 格式时存在时区歧义
// 推荐格式:清晰、无歧义、兼容所有系统
JSONWriter.config(JSONWriter.Feature.WriteDateUseDateFormat, true);
JSONWriter.config(JSONWriter.Feature.WriteDateAsJSONString, false); // 不输出为 ISO 字符串
}
// 【实战】测试输出
public static void main(String[] args) {
init(); // ⚠️ 必须在项目启动时调用一次,如 Spring Boot 的 @PostConstruct
LocalDateTime now = LocalDateTime.now();
User user = new User(1001L, "王五", "wangwu@company.com", now);
String json = JSON.toJSONString(user);
System.out.println("【全局日期格式】:");
System.out.println(json);
// 输出:{"id":1001,"name":"王五","email":"wangwu@company.com","createTime":"2025-10-15 11:30:00"}
// ✅ 所有对象日期字段统一为该格式,无需每个类都写 @JSONField(format=...)
}
}
✅ 注释说明:
- 禁止在每个类中重复写
format,应全局配置 + 局部覆盖。- 推荐格式:
yyyy-MM-dd HH:mm:ss,不推荐yyyy-MM-dd'T'HH:mm:ss(ISO)用于 API 响应。- 该配置必须在 Spring Boot 启动类或配置类中初始化,确保全局生效。
3.2 处理 BigDecimal 精度问题(金融系统必备)
import com.alibaba.fastjson2.JSON;
import java.math.BigDecimal;
// 【标准做法】自定义 BigDecimal 序列化器,避免科学计数
public class BigDecimalSerializer {
// ✅ 静态单例,线程安全,可复用
public static final JSONWriter.ObjectSerializer INSTANCE = new JSONWriter.ObjectSerializer() {
@Override
public void write(JSONWriter jsonWriter, Object value, Object fieldName, java.lang.reflect.Type fieldType, long features) {
if (value instanceof BigDecimal bd) {
// ✅ 强制保留两位小数,使用 toPlainString() 避免 1.23E+4
jsonWriter.write(bd.setScale(2, java.math.RoundingMode.HALF_UP).toPlainString());
} else {
jsonWriter.writeNull();
}
}
};
}
// 【注册序列化器】—— 推荐在 Spring 配置中注册
import com.alibaba.fastjson2.writer.ObjectWriterProvider;
public class BigDecimalConfig {
public static void register() {
// ✅ 注册到全局 WriterProvider,所有 BigDecimal 字段自动使用该格式
ObjectWriterProvider provider = new ObjectWriterProvider();
provider.put(java.math.BigDecimal.class, BigDecimalSerializer.INSTANCE);
// ✅ 设置为默认 Provider(推荐在 Spring Boot 启动时调用)
JSONWriter.config(provider);
}
public static void main(String[] args) {
register(); // ⚠️ 必须在项目启动时调用
Order order = new Order(5001L, new BigDecimal("12345.6789"), null, null, null, null);
String json = JSON.toJSONString(order);
System.out.println("【BigDecimal 标准输出】:");
System.out.println(json);
// 输出:{"order_id":5001,"total_amount":"12345.68"} ✅ 精确保留两位小数,无科学计数
}
}
✅ 注释说明:
- 金融、支付、电商系统必须使用此方案,避免金额精度丢失。
toPlainString()是关键,toString()可能输出1.23E+4,前端无法解析。- 不要使用
@JSONField(format = "0.00")—— 该格式仅适用于数字类型,对BigDecimal无效。
3.3 忽略空值字段(减少传输体积)
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
// 【标准做法】全局配置:不输出 null 字段(默认行为)
public class NullValueConfig {
public static void init() {
// ✅ 推荐:生产环境默认关闭 null 字段输出(减少 20%+ 带宽)
JSONWriter.config(JSONWriter.Feature.WriteNulls, false);
JSONWriter.config(JSONWriter.Feature.WriteMapNullValue, false);
}
public static void main(String[] args) {
init();
User user = new User(1001L, "赵六", null, LocalDateTime.now()); // email 为 null
String json = JSON.toJSONString(user);
System.out.println("【忽略 null 字段】:");
System.out.println(json);
// 输出:{"id":1001,"name":"赵六","createTime":"2025-10-15 11:30:00"}
// ✅ email 字段被自动过滤,不出现 "email":null
}
}
✅ 注释说明:
- 禁止开启
WriteNulls,除非前端明确要求null表示“未设置”。- 在微服务通信中,null 字段会增加网络开销与解析复杂度。
- 前端应使用
obj?.email ?? '未知'处理缺失字段,而非依赖null。
✅ 四、企业级实战建议(落地规范)
| 场景 | 推荐做法 | 禁止做法 |
|---|---|---|
| API 响应 | 返回 Java 对象,由 Spring Boot 自动序列化 | 手动调用 JSON.toJSONString() 返回 String |
| API 请求 | 使用 @RequestBody User user | 使用 @RequestBody String json + 手动 parse |
| Redis 缓存 | 使用 JSON.toJSONString(obj) 存储,JSON.parseObject(json, T.class) 读取 | 使用 Java 原生序列化(ObjectOutputStream) |
| 日志记录 | JSON.toJSONString(logObj, JSONWriter.Feature.WriteDateUseDateFormat) | log.info(user.toString()) |
| 配置文件 | 使用 .json 文件 + JSON.parseObject(json, Config.class) | 使用 .properties 读取复杂结构 |
| 字段命名 | 所有字段使用 @JSONField(name = "snake_case") 统一命名 | 混用 camelCase 和 snake_case |
| 敏感字段 | @JSONField(serialize = false, deserialize = false) | 使用 transient(不安全,易被忽略) |
| 日期格式 | 全局配置 WriteDateUseDateFormat + yyyy-MM-dd HH:mm:ss | 使用 @JSONField(format = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") |
| 金额字段 | 自定义 BigDecimalSerializer + setScale(2, HALF_UP) | 使用 Double 或 @JSONField(format = "0.00") |
| 泛型集合 | JSON.parseObject(json, JSON.parseType("List<User>")) | JSON.parseArray(json, User.class) |
✅ 五、Spring Boot 集成标准配置(推荐)
配置类:FastJson2Config.java
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.writer.ObjectWriterProvider;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
public class FastJson2Config {
@PostConstruct
public void init() {
// ✅ 1. 全局日期格式统一(企业标准)
JSONWriter.config(JSONWriter.Feature.WriteDateUseDateFormat, true);
JSONWriter.config(JSONWriter.Feature.WriteDateAsJSONString, false);
// ✅ 2. 全局不输出 null 字段(减少传输)
JSONWriter.config(JSONWriter.Feature.WriteNulls, false);
JSONWriter.config(JSONWriter.Feature.WriteMapNullValue, false);
// ✅ 3. 全局 BigDecimal 格式化(金融系统必备)
ObjectWriterProvider provider = new ObjectWriterProvider();
provider.put(java.math.BigDecimal.class, BigDecimalSerializer.INSTANCE);
JSONWriter.config(provider);
// ✅ 4. 禁用危险特性(安全红线)
JSONWriter.config(JSONWriter.Feature.WriteClassName, false); // 绝对禁止!
JSONWriter.config(JSONWriter.Feature.SupportAutoType, false); // 绝对禁止!
System.out.println("✅ FastJSON2 全局配置初始化完成");
}
}
✅ 说明:
- 此配置类由 Spring 容器自动加载,确保项目启动即生效。
- 所有 Controller 无需修改,直接返回 POJO,Spring Boot 会自动使用 FastJson2 序列化。
- 验证方式:启动后访问
/api/user,查看响应是否为yyyy-MM-dd HH:mm:ss格式。
✅ 六、总结:FastJson2 标准使用黄金法则
| 黄金法则 | 说明 |
|---|---|
| ✅ 类型安全 | 所有反序列化必须指定具体类型,禁止 Object.class |
| ✅ 安全第一 | 禁用 WriteClassName、SupportAutoType,敏感字段 serialize=false |
| ✅ 全局统一 | 日期、金额、null 处理必须在 @PostConstruct 中初始化 |
| ✅ 注解驱动 | 使用 @JSONField 控制字段名、格式、是否输出,而非硬编码 |
| ✅ 性能优先 | 复用 JSONWriter 实例,避免频繁创建 |
| ✅ 团队规范 | 制定《FastJSON2 使用手册》,纳入代码审查清单 |
🔚 最终建议:推动团队落地的 3 步法
- 制定标准文档:将本文档作为团队 Wiki 的《FastJson2 开发规范》。
- 自动化检查:在 CI/CD 中加入 SonarQube 规则,检测是否使用
JSON.parseObject(json, Object.class)。 - 代码评审强制项:所有涉及 JSON 的 PR,必须检查:
- 是否使用
JSON.toJSONString(obj)? - 是否禁用了敏感字段?
- 是否使用了
@JSONField? - 是否全局配置了日期格式?
- 是否使用
💡 记住:
FastJson2 不是“用起来就行”的工具,而是企业级系统安全与性能的基石。
你今天的规范,就是明天系统的稳定。
5万+

被折叠的 条评论
为什么被折叠?



