| 類別 | 對應 JSON 結構 | 主要用途 |
JSONObject | Object {...} | 鍵值對集合,支援巢狀 Object/Array |
JSONArray | Array [...] | 有序值序列,元素可為基本型別/Object/Array |
JSONException | -- | 解析/操作錯誤例外 |
一、建構 JSON 資料 (序列化)
1. 建立單一物件
JSONObject obj = new JSONObject();
obj.put("name", "落埃無蒂");
obj.put("age", 16);
obj.put("gender", "male");
// 產生: {"name":"落埃無蒂","age":16,"gender":"male"}
String jsonString = obj.toString();
2. 建立陣列結構
JSONArray array = new JSONArray();
array.put("item1");
array.put(123);
array.put(true);
// 巢狀物件
JSONObject child = new JSONObject();
child.put("key", "value");
array.put(child);
// 產生: ["item1",123,true,{"key":"value"}]
String jsonArrayString = array.toString();
3. 實務模式:Model 類別自訂 toJSON()
public class User {
public String name;
public int age;
public String[] tags;
public JSONObject toJSON() throws JSONException {
JSONObject obj = new JSONObject();
obj.put("name", name);
obj.put("age", age);
if (tags != null) {
JSONArray arr = new JSONArray();
for (String t : tags) arr.put(t);
obj.put("tags", arr);
}
return obj;
}
}
二、解析 JSON 資料 (反序列化)
1. 解析物件結構
String json = "{\"age\":\"16\",\"name\":\"落埃無蒂\",\"gender\":\"male\"}";
// 必須以 { 開頭
JSONObject obj = new JSONObject(json);
String name = obj.getString("name"); // "落埃無蒂"
int age = obj.getInt("age"); // 16 (自動轉型)
boolean isMale = "male".equals(obj.getString("gender"));
// 檢查鍵是否存在
if (obj.has("email")) {
String email = obj.getString("email");
}
// 取得所有鍵
Enumeration keys = obj.keys();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
Object value = obj.get(key);
// ...
}
2. 解析陣列結構
String json = "[{\"age\":\"16\",\"name\":\"samyou\"},{\"age\":\"18\",\"name\":\"ygy\"}]";
// 必須以 [ 開頭
JSONArray array = new JSONArray(json);
int len = array.length();
for (int i = 0; i < len; i++) {
JSONObject item = array.getJSONObject(i);
String name = item.getString("name");
int age = item.getInt("age");
// 處理每筆資料...
}
3. 安全解析工具方法 (建議封裝)
public class JSONUtil {
public static String optString(JSONObject obj, String key, String def) {
try { return obj.has(key) ? obj.getString(key) : def; }
catch (JSONException e) { return def; }
}
public static int optInt(JSONObject obj, String key, int def) {
try { return obj.has(key) ? obj.getInt(key) : def; }
catch (JSONException e) { return def; }
}
public static JSONObject optObject(JSONObject obj, String key) {
try { return obj.has(key) ? obj.getJSONObject(key) : null; }
catch (JSONException e) { return null; }
}
public static JSONArray optArray(JSONObject obj, String key) {
try { return obj.has(key) ? obj.getJSONArray(key) : null; }
catch (JSONException e) { return null; }
}
}
三、J2ME 環境特殊考量
- 記憶體限制:避免一次載入巨大 JSON,考慮串流解析 (需第三方庫如
json-simple 或自寫 Pull Parser)
- 字元編碼:網路傳輸統一使用 UTF-8,
new JSONObject(new String(bytes, "UTF-8"))
- 例外處理:所有
get/put 方法拋出 JSONException (checked),必須捕捉
- 效能:
toString() 產生緊湊格式 (無空白);若需美化輸出可用 toString(indent) (較新版本支援)
四、完整範例:HTTP 請求回傳 JSON 解析
public void fetchUserList(String url) {
HttpConnection conn = null;
InputStream is = null;
try {
conn = (HttpConnection) Connector.open(url);
conn.setRequestMethod(HttpConnection.GET);
is = conn.openInputStream();
// 讀取完整回應
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = is.read(buf)) > 0) baos.write(buf, 0, len);
String json = new String(baos.toByteArray(), "UTF-8");
// 解析
JSONArray users = new JSONArray(json);
for (int i = 0; i < users.length(); i++) {
JSONObject u = users.getJSONObject(i);
String name = JSONUtil.optString(u, "name", "Unknown");
int age = JSONUtil.optInt(u, "age", 0);
// 更新 UI 或儲存 RMS...
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try { if (is != null) is.close(); } catch (Exception ignore) {}
try { if (conn != null) conn.close(); } catch (Exception ignore) {}
}
}
總結
org.json.me 提供了 J2ME 環境下最標準、輕量的 JSON 處理能力。掌握 JSONObject/JSONArray 的建構與解析模式,搭配安全工具方法,即可高效實現行動應用與後端的 JSON 資料交換。
- 上一篇文章: J2ME 3D 程式設計實戰:第一個 M3G 程式完整原始碼解析
- 下一篇文章: J2ME/J2EE 架構下 JSON 資料交換框架設計與實作分析
Copyright ©
程式碼之家 All Rights Reserved