凌空异常错误时,响应code 304和200 [英] Volley exception error when response code 304 and 200

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

问题描述

在摆弄凌空图书馆,我发现做一个职位时 JsonObjectRequest ,如果服务器返回一个code 304或200的响应没有数据(response.data),凌空跨$ P $点它作为一个错误的反应,而不是成功。

我管理,加入了几个code线的方法响应&LT来解决它;的JSONObject> parseNetworkResponse(NetworkResponse响应)在类 JsonObjectRequest.java

  @覆盖
受保护的响应和LT;的JSONObject> parseNetworkResponse(NetworkResponse响应){
    尝试 {
        如果(!response.notModified){//增加了304响应
            字符串jsonString =新的String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            返回Response.success(新的JSONObject(jsonString)
                    HttpHeaderParser.parseCacheHeaders(响应));
        信息} else //增加了304响应
            返回Response.success(新的JSONObject(),HttpHeaderParser.parseCacheHeaders(响应));
    }赶上(UnsupportedEncodingException E){
        Log.v(排球,UnsupportedEncodingException+ response.status code);
        如果(response.status code == 200)//增加了200响应
            返回Response.success(新的JSONObject(),HttpHeaderParser.parseCacheHeaders(响应));
        其他
            返回Response.error(新ParseError(e)条);
    }赶上(JSONException JE){
        Log.v(排球,JSONException+ response.status code);
        如果(response.status code == 200)//增加了200响应
            返回Response.success(新的JSONObject(),HttpHeaderParser.parseCacheHeaders(响应));
        其他
            返回Response.error(新ParseError(JE));
    }
}
 

是不是对于这个问题的最佳解决方案?

谢谢!

修改

检查类 BasicNetwork.java 我意识到,排球检查是否有响应被询问是否 HTT presponse.getEntity没有数据( )!= NULL

  //一些反应,如204S不具备的内容。我们必须检查。
    如果(HTT presponse.getEntity()!= NULL){
        responseContents = entityToBytes(HTT presponse.getEntity());
    }其他{//添加0字节的回应,以此老老实实重新presenting一个
    //没有内容的请求。
        responseContents =新的字节[0];
    }
 

但问题仍然是,当排球尝试创建一个新的字符串 response.data发生==新的字节[0] 在parseNetworkResponse方法。<的JSONException / P>

解决方案

Miguel-是不是这种方法被称为只有当它成功响应?

有关的所有状态codeS&LT; 200或状态code> 200抽射调用parseNetworkError(VolleyError volleyError),而不是parseNetworkResponse(NetworkResponse响应)的方法。看看这里 -

<一个href="https://android.googlesource.com/platform/frameworks/volley/+/master/src/com/android/volley/toolbox/BasicNetwork.java">https://android.googlesource.com/platform/frameworks/volley/+/master/src/com/android/volley/toolbox/BasicNetwork.java

行号-118-120

 如果(状态$ C $℃下200 ||状态code&GT; 299){
                抛出新IOException异常();
   }
 

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

 赶上(IOException异常E){
            INT状态code = 0;
            NetworkResponse networkResponse = NULL;
            如果(HTT presponse!= NULL){
                。状态code = HTT presponse.getStatusLine()的getStatus code();
            } 其他 {
                抛出新NoConnectionError(E);
            }
            VolleyLog.e(意外的响应code%D%s的,状态code,request.getUrl());
            如果(responseContents!= NULL){
                networkResponse =新NetworkResponse(状态code,responseContents,
                        responseHeaders响应,假);
                如果(状态code == HttpStatus.SC_UNAUTHORIZED ||
                        状态code == HttpStatus.SC_FORBIDDEN){
                    attemptRetryOnException(身份验证,
                            的要求,新的AuthFailureError(networkResponse));
                } 其他 {
                    // TODO:只有扔SERVERERROR为5xx的状态codeS。
                    抛出新SERVERERROR(networkResponse);
                }
            } 其他 {
                抛出新NetworkError(networkResponse);
            }
        }
 

如果你想改变这种行为,您可以添加内部BasicNetwork.java-> performRequest您的状态code具体的实现方法。

编辑: 所以,不能因为身份code的,但由于空响应。嗯,我认为你正在做正确的事,实现您的自定义请求类。 凌空带有pdefined流行的类型,易于使用的请求数$ P $,但你总是可以创建自己的。 相反的状态code根据实施我宁愿简单地检查以下字符串为空deserialzing之前 -

 字符串jsonString =新的String(response.data,
                HttpHeaderParser.parseCharset(response.headers));
如果(!jsonString .isEmpty()){
                 返回Response.success(新的JSONObject(jsonString)
                HttpHeaderParser.parseCacheHeaders(响应));
}
其他 {
返回Response.success(新的JSONObject()
                    HttpHeaderParser.parseCacheHeaders(响应));
}
 

**没有测试过这一点,但你明白了吧:)

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.

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?

Thanks!

EDIT

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

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- Isn't this method called only if its a success 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

Line number -118-120

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

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

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

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 :)

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

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