当前位置:  开发笔记 > 编程语言 > 正文

当error.networkResponse为null时,Android Volley中的Http状态代码

如何解决《当error.networkResponse为null时,AndroidVolley中的Http状态代码》经验,为你挑选了3个好方法。

我在Android平台上使用Google Volley.我遇到一个问题,其中error参数in onErrorResponse返回null networkResponse 对于我正在使用的RESTful API,我需要确定Http状态代码,它经常以401(SC_UNAUTHORIZED)或500(SC_INTERNAL_SERVER_ERROR)到达,我偶尔可以检查通过:

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

这会抛出一个NullPointerException因为networkResponsenull.

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

或者,我如何确保error.networkResponse非空onErrorResponse



1> rperryng..:

或者,我如何确保onErrorResponse中的error.networkResponse为非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

public class GsonRequest extends Request {

    ...
    private int mStatusCode;

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

    @Override
    protected Response 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类的工具箱类之一并且您不想混淆实现parseNetworkResponse(NetworkResponse networkResponse),请继续覆盖该方法,但通过以下方式返回超级实现super.parseNetworkResponse(networkResponse)

例如 StringResponse

public class MyStringRequest extends StringRequest {

    private int mStatusCode;

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

    public int getStatusCode() {
        return mStatusCode;
    }

    @Override
    protected Response 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() {

                @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() {

                    @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 parseNetworkResponse(NetworkResponse response) {
                        mStatusCode = response.statusCode;
                        return super.parseNetworkResponse(response);
                    }
                };
    MyVolley.getRequestQueue.add(request);
}

更新:
HttpStatus已弃用.请HttpURLConnection改用.见链接.



2> David Manpea..:

排球不支持401

事实证明,如果没有修改Google Volley代码,则无法保证error.networkResponse为非null,因为Volley中的一个错误会在设置之前抛出BasicNetwork.java(134)中的NoConnectionErrorHttp状态代码401(HttpStatus.SC_UNAUTHORIZED)的异常.的价值networkResponse.

变通

在这种情况下,我们的解决方案不是修复Volley代码,而是修改Web Service API以HttpStatus.SC_FORBIDDEN针对特定情况发送Http Error Code 403().

对于此Http状态代码,error.networkResponseVolley错误处理程序中的值为非null : public void onErrorResponse(VolleyError error). 而且,error.networkResponse.httpStatusCode正确回报HttpStatus.SC_FORBIDDEN.

其他-建议

Rperryng关于扩展课程的建议Request可能提供了一个解决方案,并且是一个创造性和优秀的想法.非常感谢您的详细示例.我发现我们案例的最佳解决方案是使用解决方法,因为我们很幸运能够控制Web服务API.

如果我无法在服务器上进行简单的更改,我可能会选择将Volley代码修复到BasicNetwork.java中的一个位置.



3> Tolga Okur..:

Volley支持HTTP 401 Unauthorized响应.但是这个响应必须包括"WWW-Authenticate"头字段.

没有此标头,401响应会导致"com.android.volley.NoConnectionError: java.io.IOException: No authentication challenges found"错误.

有关更多详细信息,请访问:https://stackoverflow.com/a/25556453/860189

如果您使用第三方API并且无权更改响应标头,则可能会考虑实施您自己的HttpStack,因为HurlStack会抛出此异常.或者更好,使用OkHttpStack作为HttpStack.

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有