凌空异常错误时,响应code 304和200 [英] Volley exception error when response code 304 and 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 -
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屋!