Android处理错误json数据

此前一直都没遇到也一直相信服务端返回的json数据基本是正确的,直到我们的android端一直崩溃,并在友盟上查到一直报如下的错误:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:200)
    at com.google.gson.Gson.fromJson(Gson.java:810)
    at com.google.gson.Gson.fromJson(Gson.java:775)
    at com.google.gson.Gson.fromJson(Gson.java:724)
    at com.google.gson.Gson.fromJson(Gson.java:696)
    at com.hjwang.netdoctor.c.a.a(CheckVersionHelper.java:65)
    at com.hjwang.netdoctor.d.m.a(HttpRequestAsyncTask.java:54)
    at com.hjwang.netdoctor.d.m.onPostExecute(HttpRequestAsyncTask.java:17)
    at android.os.AsyncTask.finish(AsyncTask.java:632)
    at android.os.AsyncTask.access$600(AsyncTask.java:177)
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:157)
    at android.app.ActivityThread.main(ActivityThread.java:5371)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:387)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:189)
    ... 18 more

第一行第一列报错,而且要命的是不是必现的,找到服务端的开发人员,他们也找不出来原因,更要命的是从表象看来确实是android客户端时不时的崩溃,一切的矛头全部指向了android开发人员。

为了暂时规避这个问题并且找出服务端的错误(真正的错误源头)我加入了保护措施。先看看我们的json数据形式:


{
    "sessionId": "j3demrb6pbs04jmf12kfp25332",
    "result": true,
    "code": "",
    "error": "",
    "data": {
        "addrId": "13",
        "emId": "5223",
        "regionId": "4002",
        "region": "黑龙江 齐齐哈哈 铁锋区",
        "receiver": "加隆",
        "receiverPhone": "5555",
        "address": "南纺织路9号"
    }
}

result代表返回的结果,这个我们后面会用到,data代表每个接口所返回的变化的json数据。每个请求返回的数据都是固定的格式。我们写了一个model来保存这些数据:

import com.google.gson.JsonElement;

/**
 * 网路服务请求
 *
 * @author tonyzhao
 */
public class HttpRequestResponse {
    public String sessionId;
    public boolean result;
    public String code;
    public String error;
    public JsonElement data;
}

解析json代码:

  HttpRequestResponse httpRequestResponse = new BaseRequest().parseHttpRequestResponse(httpResponse);

parseHttpRequestResponse方法:

    /**
     * 解析httpResponse
     *
     * @param httpResponse
     * @return
     */
    public HttpRequestResponse parseHttpRequestResponse(String httpResponse) {
        HttpRequestResponse response=null;
        index=httpResponse.indexOf("{");
        //如果第一个字符是大括号则进行解析
        if(index==0){  
         response = gsonParse(httpResponse, HttpRequestResponse.class);
        }else if(index!=-1){//如果是错误的json数据则进行截取解析并上传到友盟
         MobclickAgent.reportError(MyApplication.getContext(), httpResponse);
         httpResponse=httpResponse.substring(index, httpResponse.length());  
         response = gsonParse(httpResponse, HttpRequestResponse.class);
        }
        if (null == response) {
            response = new HttpRequestResponse();
            response.result = false;
        }
        return response;
    }

由于报错是报的json数据第一行第一列错误,其实也有可能是其他行其他列,我们则找到第一个大括号的位置,找到后将截取正确的json数据再进行解析。如果不是第一个就是大括号则证明是错误的json数据,将错误的json数据上传到友盟上(友盟自定义错误)。如果response为null(报JsonSyntaxException)则将response设置为flase,便于接口回调时根据解析的结果做不同的处理。

gsonParse方法:

 public <T> T gsonParse(String jsonString, Type type) {
        try {
            return new Gson().fromJson(jsonString, type);
        } catch (JsonSyntaxException e) {
             MobclickAgent.reportError(MyApplication.getContext(), e.toString()+"---"+jsonString);
            return null;
        }
    }

用Gson解析json数据如果报JsonSyntaxException 则将错误的信息和错误的json上传到友盟(友盟自定义错误统计)

posted @ 2015-09-15 16:00  挨踢人啊  阅读(694)  评论(0编辑  收藏  举报