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数据应该留心观察,才不会因为”“,而花多了时间;

  • 坑多了,那就得记录下,整理笔记可以让心情静下来 .

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