JSON-lib 是早期 Java 處理 JSON 的經典庫,雖然現代項目多遷移至 Jackson、Gson,但存量系統仍廣泛使用。本文系統整理 JSON-lib 核心用法:依賴配置、Java 對象/集合轉 JSON、JSON 轉 Java 對象,含完整代碼示例與避坑指南。
JSON-lib 依賴傳遞鏈較長,需顯式引入所有傳遞依賴:
<dependencies>
<!-- JSON-lib 核心,jdk15 分類器對應 JDK 1.5+ -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!-- 必需傳遞依賴(json-lib pom 未正確聲明,需手動補全) -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
</dependencies>
提示:若使用 JDK 8+,建議直接遷移至 Jackson 或 Gson,API 更現代、性能更優、維護更活躍。
| 類 | 用途 |
|---|---|
| JSONObject | 對應 JSON Object(鍵值對),單對象轉換核心 |
| JSONArray | 對應 JSON Array,集合/數組轉換核心 |
| JSONSerializer | 高級序列化入口,支援深度配置 |
public class Person {
private String name;
private int age;
// getter/setter/toString 省略
}
Person p = new Person();
p.setName("劉大江");
p.setAge(26);
String jsonStr = JSONObject.fromObject(p).toString();
// 結果:{"age":26,"name":"劉大江"}
List list = new ArrayList<>();
list.add(new Person("A1", 26));
list.add(new Person("A2", 23));
// List → JSON Array
String jsonArray = JSONArray.fromObject(list).toString();
// 結果:[{"age":26,"name":"A1"},{"age":23,"name":"A2"}]
// 等價寫法
String jsonArray2 = JSONSerializer.toJSON(list).toString();
Map map = new HashMap<>();
map.put("p1", new Person("A1", 26));
map.put("p2", new Person("A2", 23));
// Map → JSON Object(鍵為 JSON Key)
String jsonMap = JSONArray.fromObject(map).toString();
// 結果:[{"p2":{"name":"A2","age":23},"p1":{"name":"A1","age":26}}]
// 注意:JSONArray.fromObject(Map) 返回 JSONArray,單元素為 JSONObject
// 推薦用 JSONObject.fromObject(map) 直接獲取 JSONObject
String jsonMap2 = JSONObject.fromObject(map).toString();
// 結果:{"p2":{"name":"A2","age":23},"p1":{"name":"A1","age":26}}
String jsonStr = "[{\"name\":\"A2\",\"age\":23},{\"name\":\"A1\",\"age\":26}]";
JSONArray jsonArray = JSONArray.fromObject(jsonStr);
List list = new ArrayList<>();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObj = jsonArray.getJSONObject(i);
// 方式一:JSONObject.toBean() 單個轉換
Person p = (Person) JSONObject.toBean(jsonObj, Person.class);
list.add(p);
}
// 方式二:JSONArray.toCollection() 批量轉換(推薦)
List list2 = (List) JSONArray.toCollection(jsonArray, Person.class);
String jsonObjStr = "{\"name\":\"劉大江\",\"age\":26}";
JSONObject jsonObj = JSONObject.fromObject(jsonObjStr);
Person p = (Person) JSONObject.toBean(jsonObj, Person.class);
String jsonMapStr = "{\"p1\":{\"name\":\"A1\",\"age\":26},\"p2\":{\"name\":\"A2\",\"age\":23}}";
JSONObject jsonObj = JSONObject.fromObject(jsonMapStr);
// 需指定 Value 類型
Map map = (Map) JSONObject.toBean(
jsonObj, Map.class, new HashMap>() {{
put("p1", Person.class);
put("p2", Person.class);
}}
);
| 問題 | 解決方案 |
|---|---|
| 日期格式化 | 配置 `JsonConfig`:JsonConfig cfg = new JsonConfig(); |
| 空值處理 | cfg.setIgnoreDefaultExcludes(false); cfg.getExcludes() 控制是否輸出 null 字段 |
| 循環引用 | cfg.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT) 忽略循環引用 |
| 字段名策略 | cfg.setJsonPropertyFilter((source, name, value) -> ...) 過濾字段 |
| 泛型擦除導致反序列化失敗 | 必須顯式傳遞 `Class |
| 性能瓶頸 | JSON-lib 基於反射、單線程,高併發建議遷移 Jackson(Afterburner 模組)或 Gson |
package com.example.json;
import net.sf.json.*;
import java.util.*;
public class JsonLibDemo {
public static void main(String[] args) {
// 1. Bean -> JSON
Person p = new Person("劉大江", 26);
String json = JSONObject.fromObject(p).toString();
System.out.println("Bean->JSON: " + json);
// 2. List -> JSON Array
List list = Arrays.asList(new Person("A1", 26), new Person("A2", 23));
String jsonArray = JSONArray.fromObject(list).toString();
System.out.println("List->JSON: " + jsonArray);
// 3. Map -> JSON Object
Map map = new LinkedHashMap<>();
map.put("p1", new Person("A1", 26));
map.put("p2", new Person("A2", 23));
String jsonMap = JSONObject.fromObject(map).toString();
System.out.println("Map->JSON: " + jsonMap);
// 4. JSON Array -> List
String inputArray = "[{\"name\":\"A2\",\"age\":23},{\"name\":\"A1\",\"age\":26}]";
JSONArray ja = JSONArray.fromObject(inputArray);
List parsedList = (List) JSONArray.toCollection(ja, Person.class);
System.out.println("JSON->List: " + parsedList);
// 5. JSON Object -> Bean
String inputObj = "{\"name\":\"劉大江\",\"age\":26}";
Person parsed = (Person) JSONObject.toBean(JSONObject.fromObject(inputObj), Person.class);
System.out.println("JSON->Bean: " + parsed);
}
static class Person {
private String name;
private int age;
public Person() {}
public Person(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; }
}
}
Bean->JSON: {"age":26,"name":"劉大江"}
List->JSON: [{"age":26,"name":"A1"},{"age":23,"name":"A2"}]
Map->JSON: {"p2":{"age":23,"name":"A2"},"p1":{"age":26,"name":"A1"}}
JSON->List: [Person{name='A2', age=23}, Person{name='A1', age=26}]
JSON->Bean: Person{name='劉大江', age=26}
新項目強烈建議直接使用 Jackson 或 Gson:
// Jackson 等價代碼
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
Person p = mapper.readValue(jsonStr, Person.class);
List list = mapper.readValue(jsonArrayStr, new TypeReference>() {});
JSON-lib 完成了歷史使命,理解其用法有助於維護舊系統;新架構請擁抱現代 JSON 庫,獲得更好性能、類型安全與生態支援。