<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.47</version> <!-- 請用最新版 -->
</dependency>
| 操作 | API | 說明 |
|---|---|---|
| 對象 → JSON 字符串 | JSON.toJSONString(obj) | 最常用,支持各種配置 |
| JSON 字符串 → 對象 | JSON.parseObject(str, Clazz.class) | 指定目標類型 |
| JSON 字符串 → 泛型對象 | JSON.parseObject(str, new TypeReference<List<User>>(){}) | 保留泛型信息 |
| JSON 字符串 → JSONObject | JSON.parseObject(str) | 動態結構操作 |
| 流式寫入 | JSONWriter.of(out).writeObject(obj) | 大對象/流式輸出,低內存 |
| 流式讀取 | JSONReader.of(in).readObject() | 大文件解析,不全量載入 |
// 常用配置組合
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, // 瀏覽器兼容 (轉義 等)
JSONWriter.Feature.WriteBigDecimalAsPlain, // BigDecimal 不用科學計數法
JSONWriter.Feature.WriteEnumUsingName, // Enum 序列化為名稱而非 ordinal
JSONWriter.Feature.WriteLocalDateTimeAsISO8601, // 日期 ISO 格式
};
// 使用
String json = JSON.toJSONString(user, features);
// 或全局默認
JSONFactory.getDefaultObjectWriterProvider().config(features);
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);
// 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
);
@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 | 泛型擦除,無法知道 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。