Ошибка исключения волей, когда код ответа 304 и 200

Играя с библиотекой 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]; } 

Но проблема по-прежнему заключается в исключении JSON, которое возникает, когда Volley пытается создать новую строку с помощью response.data == new byte[0] в методе parseNetworkResponse.

Мигель. Разве этот метод не вызван, если его реакция на успех?

Для всех кодов состояния <200 или код состояния> 200 залп вызывает 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(); } 

И соответствующий блок блокировки. Номер строки – 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.

Изменить: значит, это не из-за кода состояния, а из-за пустого ответа. Хорошо, я думаю, что вы делаете правильные вещи, реализуя свой собственный класс запроса. 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)); } 

** не проверили это, но вы получите точку 🙂