Exception error by will when response code 304 and 200

While playing with the Volley library, I noticed that when creating a POST JsonObjectRequest , if the server returns 304 or 200 code without data in the response (response.data) , Volley interprets it as an error response, not success.

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

 @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 this the best solution for this problem?

Thanks!

EDIT

Checking the BasicNetwork.java class I realized that Volley checks if the answer is not responding 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 JSON exception that occurs when Volley tries to create a new row using response.data == new byte[0] in the parseNetworkResponse method.

+8
android android-volley jsonobject request
source share
1 answer

Miguel. Is this method not called if its reaction to success?

For all status codes <200 or status code> 200, a salvo calls the parseNetworkError (VolleyError volleyError) method instead of the parseNetworkResponse (NetworkResponse response) method. Look at 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 corresponding block 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 specific implementation of the status code to the BasicNetwork.java-> performRequest method.

Edit: Therefore, this is not due to a status code, but because of an empty response. Well, I think you are doing the right thing by implementing your own request class. Volley comes with several predefined popular request types for ease of use, but you can always create your own. Instead of implementing on the basis of a status code, I would simply ask to check if the next line is left before deserialization -

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

** did not test this, but you got the point :)

+6
source share

All Articles