首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

FastJSON 2.x 核心用法與避坑指南:序列化配置、循環引用、泛型反序列化、安全模式

     編輯:Java 相關知識

為什麼選 FastJSON 2.x?

  • 極致性能:基於 ASM 字節碼生成、類型緩存、零拷貝解析,較 Jackson/Gson 快 20%-50%。
  • 零依賴:單 JAR 無第三方傳遞依賴。
  • 功能豐富:支持 Kotlin、Java Record、Path/Instant、自定義 TypeAdapter、JSONPath、流式 API。
  • 安全優先:2.x 重寫解析器,默認關閉 autoType,內建黑白名單機制,徹底修復 1.x 歷史漏洞。

Maven 依賴

<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.47</version> <!-- 請用最新版 -->
</dependency>

核心 API 速覽

操作API說明
對象 → JSON 字符串JSON.toJSONString(obj)最常用,支持各種配置
JSON 字符串 → 對象JSON.parseObject(str, Clazz.class)指定目標類型
JSON 字符串 → 泛型對象JSON.parseObject(str, new TypeReference<List<User>>(){})保留泛型信息
JSON 字符串 → JSONObjectJSON.parseObject(str)動態結構操作
流式寫入JSONWriter.of(out).writeObject(obj)大對象/流式輸出,低內存
流式讀取JSONReader.of(in).readObject()大文件解析,不全量載入

序列化配置大全 (JSONWriter.Feature)

// 常用配置組合
JSONWriter.Feature[] features = {
    JSONWriter.Feature.WriteNulls,           // 輸出 null 字段
    JSONWriter.Feature.WriteNullListAsEmpty, // null 集合輸出 []
    JSONWriter.Feature.WriteNullStringAsEmpty, // null 字符串輸出 ""
    JSONWriter.Feature.WriteMapNullValue,    // Map null value 輸出
    JSONWriter.Feature.PrettyFormat,         // 格式化縮進 (調試用)
    JSONWriter.Feature.WriteClassName,       // 輸出 @type (需配合 autoType)
    JSONWriter.Feature.NotWriteDefaultValue, // 不輸出默認值 (0/false/null)
    JSONWriter.Feature.IgnoreNonFieldGetter, // 忽略非字段 getter
    JSONWriter.Feature.FieldBased,           // 基於字段而非 getter 序列化
    JSONWriter.Feature.UseSingleQuotes,      // 單引號 (非標準 JSON)
    JSONWriter.Feature.BrowserCompatible,    // 瀏覽器兼容 (轉義 

反序列化配置

JSONReader.Feature[] features = {
    JSONReader.Feature.SupportAutoType,      // 開啟 autoType (需配合白名單)
    JSONReader.Feature.UseDefaultConstructorAsPossible, // 優先無參構造器
    JSONReader.Feature.FieldBased,           // 基於字段反序列化 (含 private)
    JSONReader.Feature.IgnoreSetValueError,  // 忽略 setter 異常
    JSONReader.Feature.InitStringFieldAsEmpty, // null 字符串轉 ""
    JSONReader.Feature.TrimString,           // 字符串去首尾空白
    JSONReader.Feature.SupportSmartMatch,    // 智能匹配 (忽略大小寫/下劃線)
};

// 泛型反序列化 (核心技巧)
List users = JSON.parseObject(jsonStr, new TypeReference>() {});
// 或
Type type = new TypeToken>() {}.getType();
List users = JSON.parseObject(jsonStr, type);

安全模式:autoType 白名單機制 (2.x 核心防線)

// 1. 全局白名單 (啟動時配置)
ParserConfig.getGlobalInstance().addAccept("com.myapp.dto.");
ParserConfig.getGlobalInstance().addAccept("com.myapp.vo.");

// 2. 線程級白名單 (臨時擴展)
ParserConfig config = ParserConfig.getGlobalInstance();
config.addAccept("com.thirdparty.model.");

// 3. 代碼中指定
JSON.parseObject(json, User.class, 
    JSONReader.Feature.SupportAutoType, 
    (typeName, clazz) -> typeName.startsWith("com.myapp.") // 自定義校驗函數
);

// 4. 禁用 autoType (默認關閉,最安全)
JSON.parseObject(json, User.class); // 無 @type 也能正常反序列化

鐵律:生產環境默認關閉 autoType,僅對受信內部類型開啟白名單,絕不對外部輸入開啟。

循環引用處理

public class Node {
    public String name;
    public Node parent;   // 父節點
    public List children; // 子節點
}

// 序列化:默認拋出 StackOverflowError
// 解決:@JSONField(serialize = false) 忽略反向引用
public class Node {
    public String name;
    @JSONField(serialize = false)
    public Node parent;
    public List children;
}

// 或配置
JSONWriter.Feature.DisableCircularReferenceDetect // 不推薦,會無限遞歸
// 最佳:業務層構建無環 DTO / 使用 @JSONField(serialze=false)

日期時間處理最佳實踐

// 實體類
public class Event {
    @JSONField(format = "yyyy-MM-dd HH:mm:ss") // 序列化格式
    @JSONField(parseFormat = "yyyy-MM-dd HH:mm:ss") // 反序列化格式 (可多格式兼容)
    private LocalDateTime eventTime;
    
    @JSONField(format = "yyyy-MM-dd")
    private LocalDate eventDate;
}

// 全局默認格式
JSONFactory.getDefaultObjectWriterProvider().config(
    JSONWriter.Feature.WriteLocalDateTimeAsISO8601 // ISO 8601 標準
);
JSONFactory.getDefaultObjectReaderProvider().config(
    JSONReader.Feature.UseNativeObject // 直接讀為 LocalDateTime
);

Spring Boot 整合 (Web MVC)

@Configuration
public class FastJsonConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        
        FastJsonConfig config = new FastJsonConfig();
        config.setWriterFeatures(
            JSONWriter.Feature.WriteNulls,
            JSONWriter.Feature.WriteEnumUsingName,
            JSONWriter.Feature.WriteLocalDateTimeAsISO8601,
            JSONWriter.Feature.BrowserCompatible
        );
        config.setReaderFeatures(
            JSONReader.Feature.SupportSmartMatch,
            JSONReader.Feature.TrimString,
            JSONReader.Feature.InitStringFieldAsEmpty
        );
        // 安全:不開啟 autoType,依賴 @Type 注解或白名單
        config.setParserConfig(ParserConfig.getGlobalInstance());
        
        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        converters.add(0, converter); // 優先級最高
    }
}

常見坑點速查

現象原因解決
反序列化 Map 值為 JSONObject泛型擦除,無法知道 Value 類型用 TypeReference<Map<String, User>> 或 JSON.parseObject(json, new TypeReference<...>(){})
Long 型精度丟失 (前端 JS Number 53位)JSON 標準無長整數,JS 最大安全整數 2^53-1後端 Long 序列化為 String:@JSONField(serializeUsing = ToStringSerializer.class) 或全局 JSONWriter.Feature.WriteLongAsString
Enum 序列化為數字 (ordinal)默認行為JSONWriter.Feature.WriteEnumUsingName 或 @JSONField(serialzeEnumAsName = true)
BigDecimal 輸出科學計數法 (1E+10)默認輸出JSONWriter.Feature.WriteBigDecimalAsPlain
異常: "autoType is not support"JSON 含 @type 但未開啟/不在白名單去除 @type、或加白名單、或用具體類型反序列化

總結

FastJSON 2.x 是 Java JSON 處理的**性能之王**與**安全新標桿**。掌握 Feature 配置組合、**TypeReference 泛型保留**、autoType 白名單機制**、Long→String 精度保護**、日期格式統一、Spring MVC 整合,即可覆蓋 99% 場景。記住:安全配置不可妥協,性能優化按需開啟,泛型反序列化用 TypeReference。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved