Ⅰ.前言
昨天在解析後臺返回的json數據時,json數據一直解析失敗,剛開始以爲是kotlin的bean類問題
,因爲項目已經逐漸把開發語言從java轉爲kotlin,還是第一次使用kotlin寫bean類,但是在將bean類改爲java實現後,仍解析失敗。查看json數據,並沒發現有什麼特殊的地方,之後不斷的調試,異常不斷出現。最後終於解決了,但卻是經歷了幾個小時的異常,還是決定記錄下,畢竟多總結~才能少採坑.
Ⅱ. json解析
項目中用到的解析框架是JackSon,在解決異常的過程中,有些異常不是很明顯得看出異常原因,其中也懷疑是JackSon框架的問題,之所以懷疑JackSon框架,是因爲在該項目的前期開發時,在JackSon踩了多個坑,最後雖然也都解決了,但是卻忘記記錄那些坑。所以在昨天解析不斷異常的時候,也暫時改用手動解析,所以下面除了貼json手動解析的代碼,也有已經註釋的JackSon代碼
String script = "javascript:getBookJson();";
mWebView.evaluateJavascript(script, new ValueCallback<String>() {
@Override
public void onReceiveValue(String jsonArray) {
if (!TextUtils.equals(jsonArray,"null")){
//String jsonArray1 = jsonArray.replace("\\", "");
//jsonArray = jsonArray.substring(1);
try {
JSONArray jsonArray2 = new JSONArray(jsonArray);
int length = jsonArray2.length();
for(int i =0;i<length;i++){
LogUtil.logi("====jsonBean======" + jsonArray2.get(i).toString());
}
} catch (JSONException e) {
e.printStackTrace();
}
/*
使用JackSon框架解析的代碼
List<TestBean> enterpriseBookBeens = JacksonUtil.jsonToBeans(jsonArray, TestBean.class);
for (TestBean bean : enterpriseBookBeens) {
LogUtil.logi("==bean==" + bean.toString());
}*/
}
上面的代碼主要是調用網頁的JS方法後,返回String類型的數據並且解析. 多餘的代碼也就不貼了,主要爲了記錄下所發生的異常以及原因.
Ⅲ.滿屏的異常
“引起的問題(json手動解析報的異常)
異常信息:
06-30 18:12:43.631 9301-9301/com.wyk.test W/System.err: org.json.JSONException: Value[{"bookId":"bc557e756d3e41c986898ddad0798d3d"
...
at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONArray.<init>(JSONArray.java:96)
at org.json.JSONArray.<init>(JSONArray.java:108)
...
原因:返回的數據本來是一個數組,由 [ ] 包括着,但是卻在 [ ] 前後多了兩個”“,那就變成了”[…]”,所以解析也就出現問題,這異常信息提示是說:數據類型問題,其實點進去異常信息的Json解析源碼中,更能看得清楚,主要由於數據並不是JsonArray類型的,所以解析失敗.
怎麼解決:
- 方法1:後臺生成的數據過濾掉”[…]”的 ” ” 符號後再返回;
- 方法2:在獲取數據之後,移動端代碼進行處理,使用jsonArray.substring(1)將” 去除,之後再解析.
\\引起的問題(json手動解析報的異常)
異常信息:
org.json.JSONException: Expected literal value at character 2 of [{\"bookId\":\"bc557e756d3e41c986898ddad0798d3d\" ...
org.json.JSONTokener.syntaxError(JSONTokener.java:449)
...
原因:由於json中的某些字段值爲String類型的,其中的” “符號都是用\\” \\”這樣的形式來轉義,所以在解析過程中就出現問題了,下面是截取的json中其中一小段數據, 從log中並沒有看出特殊的,但是輸出到文件進行查看,就發現了未經轉義的\\ (這裏也是被轉義成兩個\)
"[\\\"bookId\\\": \\\"bc557e756d3e41c986898ddad0798d3d\\\",\\\"childList\\\": [],\\\"code\\\": \\\"\\\",
\\\"createTime\\\": 1496805615000,\\\"id\\\": \\\"1103\\\",\\\"isFree\\\": 0,\\\"name\\\": \\\"第一篇\\\
\t管理篇\\\",\\\"parentId\\\": \\\"0\\\",\\\"sortNo\\\": 2.0,\\\"status\\\": 1,\\\"type\\\": \\\"Section\\\",
\\\"updateTime\\\": 1496823672000},{\\\"bookId\\\": \\\"bc557e756d3e41c986898ddad0798d3d\\\",
\\\"childList\\\": [],\\\"code\\\": \\\"\\\",\\\"createTime\\\": 1496805884000,\\\"id\\\": \\\"1104\\\",
\\\"isFree\\\": 0,\\\"name\\\": \\\"第1章前言\\\",\\\"parentId\\\": \\\"1103\
\\",\\\"sortNo\\\": 3.0,\\\"status\\\": 1,\\\"type\\\": \\\"Section\\\",\\\"updateTime\\\": 1496823686000}, ...]
怎麼解決:
- 後臺生成的數據過濾掉”\\”的 ” ” 符號再返回;
- 移動端在獲取數據之後,使用jsonArray.replace(“\\”, “”)進行過濾.
眼花導致的問題
異常信息:
org.json.JSONException: Unterminated string at character 1 of "
06-30 18:40:10.087 5951-5951/com.wyk.test W/System.err:at org.json.JSONTokener.syntaxError(JSONTokener.java:449)
06-30 18:40:10.087 5951-5951/com.wyk.test W/System.err:at org.json.JSONTokener.nextString(JSONTokener.java:228)
06-30 18:40:10.087 5951-5951/com.wyk.test W/System.err:at org.json.JSONTokener.nextValue(JSONTokener.java:107)
原因:由於jsonArray兩邊帶了”[ ]”,移動端對數據進行處理後再解析,jsonArray = jsonArray.substring(jsonArray.length()-1)所導致的,本來我是打算切掉 [ ] 兩邊的”“,但卻寫錯了,所以數據切割後只剩下” , 應該是jsonArray.subString(1,jsonArrray.length-1)才正確
\\引起的問題(JackSon框架解析報的異常)
異常信息:
com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('\' (code 92)): was expecting double-quote to start field name
at [Source: [{\"bookId\":\"bc557e756d3e41c986898ddad0798d3d\",\" ...
...
原因:跟上面的原因一樣,數據中多了\, 可JackSon報的異常信息跟json手動解析報的異常並不一樣
“引起的問題(JackSon框架解析報的異常)
異常信息:
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token
at [Source: "[{"bookId":"bc557e756d3e41c986898ddad0798d3d","childList":[] ...
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:873)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:869)
...
原因:跟上面的原因一樣,多了”“這符號,異常說不是ArrayList類型,但JackSon報的異常信息跟json手動解析報的異常並不一樣
ClassCastException異常
異常信息
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.wyk.test.kotlin.test.TestBean
備註:這是前一項目使用的Gson框架報的異常信息,在此一併貼上
參考方案:http://blog.csdn.net/xiaojieblog/article/details/52585509
Ⅳ.總結
之所以將上面相同原因導致的,不一樣的異常信息列舉出來,主要是爲了避免再採坑,就跟避免造輪子同個道理, 前人採坑,後人躲坑;
在開發中,遇到json數據應該留心觀察,纔不會因爲”“,而花多了時間;
坑多了,那就得記錄下,整理筆記可以讓心情靜下來 .