我在Android平台上使用Google Volley。
我遇到一个问题,其中error中的onErrorResponse参数返回空networkResponse对于我正在使用的RESTful API,我需要确定通常以401(SC_UNAUTHORIZED)或500(SC_INTERNAL_SERVER_ERROR)形式到达的Http状态代码,并且我偶尔可以通过以下方式进行检查:

final int httpStatusCode = error.networkResponse.statusCode;
if(networkResponse == HttpStatus.SC_UNAUTHORIZED) {
    // Http status code 401: Unauthorized.
}

因为NullPointerException为null,所以将抛出networkResponse

如何确定函数onErrorResponse中的Http状态代码?

或者,如何确保error.networkResponseonErrorResponse中为非null?

最佳答案



我的第一个想法是检查对象是否为null。

@Override
public void onErrorResponse(VolleyError error) {
    NetworkResponse networkResponse = error.networkResponse;
    if (networkResponse != null && networkResponse.statusCode == HttpStatus.SC_UNAUTHORIZED) {
        // HTTP Status Code: 401 Unauthorized
    }
}

另外,您还可以尝试通过扩展Request类并覆盖parseNetworkResponse来获取状态码。

例如,如果扩展抽象Request<T>
public class GsonRequest<T> extends Request<T> {

    ...
    private int mStatusCode;

    public int getStatusCode() {
        return mStatusCode;
    }
    ...

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {

        mStatusCode = response.statusCode;
        try {
            Log.d(TAG, "[raw json]: " + (new String(response.data)));
            Gson gson = new Gson();
            String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            return Response.success(gson.fromJson(json, mClazz),
                HttpHeaderParser.parseCacheHeaders(response));

        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e) {
            return Response.error(new ParseError(e));
        }
    }
    ...
}

或者,如果您正在使用已经扩展了抽象Request<T>类的工具箱类之一,并且不想弄混parseNetworkResponse(NetworkResponse networkResponse)的实现,请继续重写该方法,但通过super.parseNetworkResponse(networkResponse)返回上级的实现

例如StringResponse
public class MyStringRequest extends StringRequest {

    private int mStatusCode;

    public MyStringRequest(int method, String url, Listener<String> listener,
            ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }

    public int getStatusCode() {
        return mStatusCode;
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        mStatusCode = response.statusCode;
        return super.parseNetworkResponse(response);
    }
}

用法:
public class myClazz extends FragmentActivity {


    private Request mMyRequest;
    ...

    public void makeNetworkCall() {
    mMyRequest = new MyNetworkRequest(
            Method.GET,
            BASE_URL + Endpoint.USER,
            new Listener<String>() {

                @Override
                public void onResponse(String response) {
                    // Success

                }
            },
            new ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    if (mMyRequest.getStatusCode() == 401) {
                        // HTTP Status Code: 401 Unauthorized
                    }
                }
            });

    MyVolley.getRequestQueue().add(request);
}

当然,也可以使用覆盖方法内联的选项
public class MyClazz extends FragmentActivity {

    private int mStatusCode;

    ...

    public void makeNetworkCall() {

        StringRequest request = new StringRequest(
                Method.GET,
                BASE_URL + Endpoint.USER,
                new Listener<String>() {

                    @Override
                    public void onResponse(String response) {
                        // Success

                    }
                },
                new ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        if (mStatusCode == 401) {
                            // HTTP Status Code: 401 Unauthorized
                        }
                    }
                }) {

                    @Override
                    protected Response<String> parseNetworkResponse(NetworkResponse response) {
                        mStatusCode = response.statusCode;
                        return super.parseNetworkResponse(response);
                    }
                };
    MyVolley.getRequestQueue.add(request);
}

更新:
不推荐使用HttpStatus。请改用HttpURLConnection。参见Link

10-02 06:13