前後端分離架構中,後端常需將前端傳來的 JSON 陣列字串反序列化為強型別 List<T>。本文以 json-lib(JSONArray)為例,示範完整轉換流程,並對比主流庫(Jackson、Gson、Fastjson)的最佳實踐。
// JSON 字串範例
[{"userid":"admin","name":"admin","password":"MTIzNDU2","flag":1,"createtime":1467277229000,"nickname":"","thumbnail":null,"lastDate":null,"status":null,"region":"22222"},
{"userid":"administrator","name":"administrator","password":"MTIzNDU2","flag":0,"createtime":1467252566000,"nickname":"超級管理員用戶","thumbnail":null,"lastDate":null,"status":null,"region":""}]
// 對應 Java Bean
public class User {
private String userid, name, password, nickname, thumbnail, region;
private Byte flag, status;
private Date createtime, lastDate;
// Getter/Setter 省略(建議用 Lombok @Data)
}
import net.sf.json.JSONArray;
import java.util.*;
String listUsers = userClient.listUsers(); // 獲取 JSON 字串
JSONArray jArray = JSONArray.fromObject(listUsers);
Collection collection = JSONArray.toCollection(jArray, User.class); // 核心:指定目標類
List userList = new ArrayList<>(collection); // 直接構造 List
// 或手動迭代(舊版本兼容)
List userList = new ArrayList<>();
Iterator it = collection.iterator();
while (it.hasNext()) {
userList.add((User) it.next());
}
關鍵點:JSONArray.toCollection(jsonArray, TargetClass.class) 內部使用反射實例化 Bean 並設定屬性,要求 Bean 有無參構造函數與 Setter。
| 庫 | Maven 坐標 | 核心 API | 優勢 | 適用場景 |
|---|---|---|---|---|
| Jackson | com.fasterxml.jackson.core:jackson-databind | objectMapper.readValue(json, new TypeReference<List<User>>(){}) | 性能最強、Spring Boot 預設、註解豐富、流式處理 | 現代專案首選 |
| Gson | com.google.code.gson:gson | gson.fromJson(json, new TypeToken<List<User>>(){}.getType()) | API 簡潔、無依賴、Kotlin 友好 | Android、輕量級 |
| Fastjson | com.alibaba:fastjson | JSON.parseArray(json, User.class) | 國產、速度快、功能全、兼容非標準 JSON | 國內高併發系統 |
| json-lib | net.sf.json-lib:json-lib | JSONArray.toCollection(array, User.class) | 老牌、依賴多、維護緩慢 | 維護舊專案 |
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; // Java 8 時間支持
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule()); // 支持 LocalDateTime
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 忽略多餘字段
List users = mapper.readValue(jsonString, new TypeReference>() {});
yyyy-MM-dd'T'HH:mm:ss) 或時間戳,配置 ObjectMapper 日期格式。mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL) 忽略 null 輸出;反序列化時 Bean 屬性為基本型別(int)遇 null 會拋異常,建議用包裝型別(Integer)。TypeReference 或 TypeToken 保留泛型資訊。JsonParser / Fastjson JSONReader 逐個對象解析,避免 OOM。JSON 陣列轉 List<Bean> 是後端開發高頻操作。新專案首選 Jackson(Spring Boot 整合零配置),Android/輕量級用 Gson,國內高併發可考慮 Fastjson。理解反射機制與泛型保留原理,能快速排查類型轉換異常。