Android開發中遇到的json解析異常問題

Ⅰ.前言

昨天在解析後臺返回的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數據應該留心觀察,纔不會因爲”“,而花多了時間;

  • 坑多了,那就得記錄下,整理筆記可以讓心情靜下來 .

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章