响应代码304和200时的排球异常错误

时间:2014-02-22 11:18:03

标签: android request android-volley jsonobject http-status-code-304

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

我设法通过在类Response<JSONObject> parseNetworkResponse(NetworkResponse response)的方法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));
    }
}

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

谢谢!

修改

检查课程BasicNetwork.java我意识到Volley会通过询问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。

1 个答案:

答案 0 :(得分:6)

Miguel-这种方法只有在成功响应时才被调用吗?

对于所有状态代码&lt; 200或状态代码&gt; 200 volley调用parseNetworkError(VolleyError volleyError)而不是parseNetworkResponse(NetworkResponse response)方法。看这里 -

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

行号-118-120

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

和相应的catch块行号 - 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-&gt; performRequest方法中添加特定于状态代码的实现。

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

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));
}

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