FastJson2 标准使用指南(企业级 Java 后端开发规范版)

以下是一份企业级 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兼容非标准前端传参(如传 UserNameusername)。
  • 不推荐在普通实体类中使用,避免耦合序列化逻辑。

✅ 三、高级功能(企业级场景专用)

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
安全第一禁用 WriteClassNameSupportAutoType,敏感字段 serialize=false
全局统一日期、金额、null 处理必须在 @PostConstruct 中初始化
注解驱动使用 @JSONField 控制字段名、格式、是否输出,而非硬编码
性能优先复用 JSONWriter 实例,避免频繁创建
团队规范制定《FastJSON2 使用手册》,纳入代码审查清单

🔚 最终建议:推动团队落地的 3 步法

  1. 制定标准文档:将本文档作为团队 Wiki 的《FastJson2 开发规范》。
  2. 自动化检查:在 CI/CD 中加入 SonarQube 规则,检测是否使用 JSON.parseObject(json, Object.class)
  3. 代码评审强制项:所有涉及 JSON 的 PR,必须检查:
    • 是否使用 JSON.toJSONString(obj)
    • 是否禁用了敏感字段?
    • 是否使用了 @JSONField
    • 是否全局配置了日期格式?

💡 记住
FastJson2 不是“用起来就行”的工具,而是企业级系统安全与性能的基石。
你今天的规范,就是明天系统的稳定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值