当前位置: 首页 > 知识库问答 >
问题:

error.networkResponse为空时Android凌空中的Http状态代码

刘德义
2023-03-14

我在Android平台上使用谷歌排球。我遇到了一个问题,其中错误参数在错误响应返回网络响应对于我正在使用的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.
}

这将引发空点异常,因为网络响应为空。

如何确定错误响应函数中的 Http 状态代码?

或者,如何确保< code>onErrorResponse中的< code > error . network response 不为空?

共有3个答案

赫连淳
2023-03-14
匿名用户

凌空支持 HTTP 401 未经授权的响应。但此响应必须包括“WWW 身份验证”标头字段。

如果没有此标头,401响应会导致< code >“com . Android . volley . No connection error:Java . io . io exception:No authentic ation challenges found”错误。

更多细节:https://stackoverflow.com/a/25556453/860189

如果您使用第三方API并且无权更改响应头,您可以考虑实现自己的HttpStack,因为这个异常是由HurlStack抛出的。或者更好的是,使用OkHttpStack作为HttpStack。

祁聪
2023-03-14

事实证明,这是不可能保证的错误。networkResponse在不修改Google Volley代码的情况下为非null,因为Volley中的一个错误会在BasicNetwork中为Http状态代码401(HttpStatus.SC_UNAUTHORIZED)引发ExceptionNoConnectionError。java(134),然后设置networkResponse的值。

在这种情况下,我们的解决方案不是修复截击代码,而是修改Web服务API来发送Http错误代码403 (HttpStatus。SC_FORBIDDEN)用于所讨论的特定情况。

对于此 Http 状态代码,error.network响应的值在排球错误处理程序中为非空:错误响应(排球错误错误)上的公共无效。并且,错误网络响应状态代码正确返回HttpStatus.SC_FORBIDDEN

雷佩林关于延长请求的建议

如果我不能在服务器上进行简单的修改,我可能会选择在BasicNetwork.java的某个地方修复凌空代码。

尉迟明贤
2023-03-14

或者,如何确保error.networkResponse在onErrorResponse中为非空?

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

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

或者,您也可以尝试通过扩展请求类并重写解析网络响应来获取状态代码。

例如,如果扩展抽象请求

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

例如< code>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);
}

更新:< br> HttpStatus已被否决。请改用< code>HttpURLConnection。参见链接。

 类似资料:
  • 我正在从服务器下载文件。我用排球来做。 这是我的代码 以下是错误侦听器的错误消息在一些弱网络连接上,我收到以下逻辑消息 我不明白失败的原因是什么,因为大多数错误消息都返回null。我很确定这是因为请求超时,我知道如何增加超时,但是我应该在错误侦听器中编写什么代码,以便在出现错误时获得正确的错误消息。

  • 关于在项目中使用截击,我有几个问题: 这个库可以在任何Java项目中使用,还是仅在Android中使用

  • 我使用的是volley.jar,在编译时没有错误,但是有运行时异常。 然后添加volley.jar和build path。什么是问题? CustomAdapter.java

  • 我在慢速网络上的Volley POST请求有问题。每次我在我的LogCat中看到BasicNetwork.logSlow请求,我的POST请求都会执行两次或更多次,导致1个请求的多次(2次或更多)发布。我已经将重试策略设置为0,但它没有帮助。 这是我的LogCat 截击(5984):[19807]基本网络。logSlowRequests:请求的HTTP响应= 这是我的密码 请帮助,我拼命寻找解决这

  • 问题内容: 我正在使用凌空特技从REST api解析电影详细信息,并将解析后的数据保存在一个名为detailsMovies的对象的Arraylist中。但是我无法在onResponse方法之外访问ArrayList。我是Android新手,所以我不知道该怎么做。任何帮助表示赞赏! 这是代码: 问题答案: 在您的课程中定义一个接口并实现它。 因此,这里的简单技巧是与回调接口。