首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android JSON 解析錯誤:雙層字串結構導致 JSONObject 初始化失敗

     編輯:程式設計綜合問答

錯誤現場

伺服器回傳 JSON:

{
  "return": "[{\"ambient\":2999,\"devLocation\":\"客廳\",...}]"
}

客戶端直接 new JSONObject(response) 拋出 Unterminated object at character ...。

根因分析

  1. 最外層是 JSONObject,只有一個鍵 return。
  2. return 的值是字串 (String),而非 JSONArray。字串內容為 JSON 陣列的字面序列化文字(含轉義引號)。
  3. 直接將整個回傳傳給 JSONObject 解析時,解析器遇到 return 後的雙引號以為字串結束,實際上字串內部還有未轉義的結構字元,導致解析器狀態機錯亂。

正確解析步驟

// 1. 先解析最外層
JSONObject outer = new JSONObject(responseString);

// 2. 取得內層字串
String innerJsonString = outer.getString("return");  // 內容為 "[{...},{...}]"

// 3. 再解析內層字串為 JSONArray
JSONArray dataArray = new JSONArray(innerJsonString);

// 4. 遍歷陣列取得每個物件
for (int i = 0; i < dataArray.length(); i++) {
    JSONObject item = dataArray.getJSONObject(i);
    int ambient = item.getInt("ambient");
    String location = item.getString("devLocation");
    // ... 其他欄位
}

伺服器端改善建議(根治)

伺服器不應將 JSON 陣列「字串化」後再放入另一個 JSON 物件。正確做法:

// 錯誤寫法 (雙重序列化)
JSONArray jArray = JSONArray.fromObject(envList);
return jArray.toString(); // 回傳字串,框架再包一層 {"return": "..."}

// 正確寫法 (直接回傳 List/陣列,讓框架序列化一次)
return envList; // 或 Map{ "data": envList }

若無法修改伺服器,客戶端務必採用「兩次解析」策略。

常見陷阱提醒

  • 使用 org.json 時注意 getString vs optString:前者缺鍵拋異常,後者回傳預設值。
  • 大量資料建議改用 Gson / Moshi / Kotlinx.serialization,自動處理巢狀結構且效能更佳。
  • 若內層字串包含 Unicode 轉義 (\uXXXX),JSONArray 建構子可正確處理,無需手動反轉義。

總結

「JSON 字串套 JSON 字串」是典型的雙重序列化錯誤。客戶端解決方法:先 JSONObject 取鍵值,再 JSONArray 解析該字串值。長遠來看,應要求伺服器修正序列化邏輯,避免雙重編碼。

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