响应代码 304 和 200 时出现 Volley 异常错误 [英] Volley exception error when response code 304 and 200

查看:30
本文介绍了响应代码 304 和 200 时出现 Volley 异常错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用 Volley 库时,我注意到在进行 POST JsonObjectRequest 时,如果服务器返回代码 304 或 200 而响应中没有数据 (response.data),Volley 将其解释为错误响应,而不是成功.

Playing around with the Volley library, I noticed that when making a POST JsonObjectRequest , if the server returns a code 304 or 200 with no data in the response (response.data), Volley interprets it as an error response, instead of a success.

我设法通过在方法 Response 中添加几行代码来解决它.parseNetworkResponse(NetworkResponse response) 类中的JsonObjectRequest.java.

I manage to solve it by adding a couple of lines of code in the method Response<JSONObject> parseNetworkResponse(NetworkResponse response) in the class JsonObjectRequest.java.

@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
    try {
        if (!response.notModified) {// Added for 304 response
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } else // Added for 304 response
            return Response.success(new JSONObject(),HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        Log.v("Volley", "UnsupportedEncodingException " + response.statusCode);
        if (response.statusCode == 200)// Added for 200 response
            return Response.success(new JSONObject(), HttpHeaderParser.parseCacheHeaders(response));
        else
            return Response.error(new ParseError(e));
    } catch (JSONException je) {
        Log.v("Volley", "JSONException " + response.statusCode);
        if (response.statusCode == 200)// Added for 200 response
            return Response.success(new JSONObject(),HttpHeaderParser.parseCacheHeaders(response));
        else
            return Response.error(new ParseError(je));
    }
}

这是解决这个问题的最佳方案吗?

Is it the best solution for this problem?

谢谢!

编辑

检查类 BasicNetwork.java 我意识到 Volley 通过询问是否 httpResponse.getEntity() != null 来检查响应是否没有数据.

Checking the class BasicNetwork.java I realized that Volley checks if a response has no data by asking if httpResponse.getEntity() != null.

// Some responses such as 204s do not have content. We must check.
    if (httpResponse.getEntity() != null) {
        responseContents = entityToBytes(httpResponse.getEntity());         
    } else {// Add 0 byte response as a way of honestly representing a
    // no-content request.
        responseContents = new byte[0];
    }

但问题仍然是当 Volley 尝试在 parseNetworkResponse 方法中使用 response.data == new byte[0] 创建新字符串时发生的 JSONException.

But the problem is still the JSONException that occurs when Volley tries to create a new string with response.data == new byte[0] in the parseNetworkResponse method.

推荐答案

Miguel- 这个方法不是只有在响应成功时才调用吗?

Miguel- Isn't this method called only if its a success response?

对于所有状态代码 <200 或状态代码 >200 的 volley 调用 parseNetworkError(VolleyError volleyError) 而不是 parseNetworkResponse(NetworkResponse response) 方法.看这里 -

For all status codes <200 or status code >200 volley invokes parseNetworkError(VolleyError volleyError) instead of parseNetworkResponse(NetworkResponse response)method. Look here -

https://android.googlesource.com/platform/frameworks/volley/+/master/src/com/android/volley/toolbox/BasicNetwork.java

行号 -118-120

Line number -118-120

  if (statusCode < 200 || statusCode > 299) {
                throw new IOException();
   }

和对应的catch块行号 - 128 -151

and the corresponding catch block Line number - 128 -151

catch (IOException e) {
            int statusCode = 0;
            NetworkResponse networkResponse = null;
            if (httpResponse != null) {
                statusCode = httpResponse.getStatusLine().getStatusCode();
            } else {
                throw new NoConnectionError(e);
            }
            VolleyLog.e("Unexpected response code %d for %s", statusCode, request.getUrl());
            if (responseContents != null) {
                networkResponse = new NetworkResponse(statusCode, responseContents,
                        responseHeaders, false);
                if (statusCode == HttpStatus.SC_UNAUTHORIZED ||
                        statusCode == HttpStatus.SC_FORBIDDEN) {
                    attemptRetryOnException("auth",
                            request, new AuthFailureError(networkResponse));
                } else {
                    // TODO: Only throw ServerError for 5xx status codes.
                    throw new ServerError(networkResponse);
                }
            } else {
                throw new NetworkError(networkResponse);
            }
        }

如果你想覆盖这个行为,你可以在 BasicNetwork.java->performRequest 方法中添加你的状态代码特定的实现.

If you want to override this behavior you can add your status code specific implementation inside BasicNetwork.java->performRequest method.

所以它不是因为状态代码而是因为空响应.好吧,我认为您正在做正确的事情来实现您的自定义 Request 类.为了便于使用,Volley 附带了一些预定义的流行请求类型,但您始终可以创建自己的请求.而不是基于状态代码的实现,我宁愿在反序列化之前简单地检查以下字符串是否为空 -

Edit : So its not because of status code but because of the empty response. Well I think you are doing the right thing implementing your custom Request class. Volley comes with a few predefined popular types of requests for ease of use, but you can always create your own. Instead of a status code based implementation i'd rather simply check if the following string is empty before deserialzing it -

String jsonString = new String(response.data,
                HttpHeaderParser.parseCharset(response.headers));
if (!jsonString .isEmpty()) {
                 return Response.success(new JSONObject(jsonString),
                HttpHeaderParser.parseCacheHeaders(response));
}
else {
return Response.success(new JSONObject(),
                    HttpHeaderParser.parseCacheHeaders(response));
}

**尚未对此进行测试,但您明白了:)

**haven't tested this, but you get the point :)

这篇关于响应代码 304 和 200 时出现 Volley 异常错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆