Android官方通信框架Volley:解析VolleyError获取包体信息

接上一篇Fiddler抓Android设备报文,虽然有了抓包工具,但是如果遇到HTTP 500这样的问题,还是很麻烦,有没有一种方法可以直接在LOGCAT中看到html报文内容呢,这样就可以快速的定位问题。

现在网络上的教程对于HTTP请求错误都是这样处理的:

StringRequest stringRequest = new StringRequest(“http://www.baidu.com”,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(“TAG”, response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(“TAG”, error.getMessage(), error);
}
});

一句
Log.e(“TAG”, error.getMessage(), error);
打印出的错误信息非常有限:

08-20 20:48:03.606: E/LOGIN-ERROR(6656): null
08-20 20:48:03.606: E/LOGIN-ERROR(6656): com.android.volley.ServerError
08-20 20:48:03.606: E/LOGIN-ERROR(6656): at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:145)
08-20 20:48:03.606: E/LOGIN-ERROR(6656): at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)

加上Volley框架打印的错误

08-20 20:49:23.452: E/Volley(6656): [1437] BasicNetwork.performRequest: Unexpected response code 500 for

你也只能判断是服务器端出现问题,但是究竟是因为请求的参数或者方式不正确?还是服务器端哪里不对了?你是无法进一步做出改变的。

除了Fiddler抓包,就没有更好的办法了吗。

既然有错误抛出,那我们来分析一下抛出错误的VolleyError类吧。

上源码:

public class VolleyError extends Exception {
public final NetworkResponse networkResponse;

public VolleyError() {
networkResponse = null;
}

public VolleyError(NetworkResponse response) {
networkResponse = response;
}

public VolleyError(String exceptionMessage) {
super(exceptionMessage);
networkResponse = null;
}

public VolleyError(String exceptionMessage, Throwable reason) {
super(exceptionMessage, reason);
networkResponse = null;
}

public VolleyError(Throwable cause) {
super(cause);
networkResponse = null;
}
}

发现有一个networkResponse对象,这个对象我们猜测含有返回的全部消息。

再打开这个类的源码。

public class NetworkResponse {
/**
* Creates a new network response.
* @param statusCode the HTTP status code
* @param data Response body
* @param headers Headers returned with this response, or null for none
* @param notModified True if the server returned a 304 and the data was already in cache
*/
public NetworkResponse(int statusCode, byte[] data, Map<String, String> headers,
boolean notModified) {
this.statusCode = statusCode;
this.data = data;
this.headers = headers;
this.notModified = notModified;
}

public NetworkResponse(byte[] data) {
this(HttpStatus.SC_OK, data, Collections.<String, String>emptyMap(), false);
}

public NetworkResponse(byte[] data, Map<String, String> headers) {
this(HttpStatus.SC_OK, data, headers, false);
}

/** The HTTP status code. */
public final int statusCode;

/** Raw data from this response. */
public final byte[] data;

/** Response headers. */
public final Map<String, String> headers;

/** True if the server returned a 304 (Not Modified). */
public final boolean notModified;

通过看注释,我们得知,data是回应报文的包体内容,只要把data解码并显示出来,那么就有可能看到更详细的错误信息,最起码是一段HTML文档。如果网站开DEBUG模式,那么肯定会有详细的错误信息。

new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(“LOGIN-ERROR”, error.getMessage(), error);
byte[] htmlBodyBytes = error.networkResponse.data;
Log.e(“LOGIN-ERROR”, new String(htmlBodyBytes), error);
}
}

经过这样改造后,logcat中的错误输出信息就变得很详细和清晰了。

版权声明:除标明转载的文章外皆为原创文章
转载请注明: 转载自Liudroid的博客,作者:Liudroid
本文链接地址: Android官方通信框架Volley:解析VolleyError获取包体信息

3 Comments

  1. wangjia said:

    Volley的异常列表:
    AuthFailureError:如果在做一个HTTP的身份验证,可能会发生这个错误。
    NetworkError:Socket关闭,服务器宕机,DNS错误都会产生这个错误。
    NoConnectionError:和NetworkError类似,这个是客户端没有网络连接。
    ParseError:在使用JsonObjectRequest或JsonArrayRequest时,如果接收到的JSON是畸形,会产生异常。
    SERVERERROR:服务器的响应的一个错误,最有可能的4xx或5xx HTTP状态代码。
    TimeoutError:Socket超时,服务器太忙或网络延迟会产生这个异常。默认情况下,Volley的超时时间为2.5秒。如果得到这个错误可以使用RetryPolicy。

    2015 年 01 月 27 日
    Reply
    • Liudroid said:

      赞,谢谢你的提醒,看来我还是了解的不够多

      2015 年 01 月 28 日
      Reply
  2. said:

    您好,我遇到了文章中说的情况,按照 error.networkResponse;这句本身不提示错误,但是用log打印是会报错误说 空对象。
    int statc = error.networkResponse.statusCode;
    String sta=getString(statc); Log.e(“test”, “status=” + sta);
    byte[] data = error.networkResponse.data;
    String datas = data.toString();
    Log.e(“test”, “data=” + datas,error);
    这样写是会报错的。

    下面这个:不会报错是对的
    String string = error.toString();
    Log.e(“test”, “错误是++++++++++” + string);
    if (error instanceof TimeoutError) {
    Toast.makeText(getApplicationContext(), “网络请求超时”, 2000).show();
    } else {
    Toast.makeText(getApplicationContext(), “未知错误”, 2000).show();
    }

    但是我想用上面你所说的方法来获取状态码信息,求大神帮忙看看

    2015 年 11 月 06 日
    Reply

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.