Volley error de excepción cuando el código de respuesta 304 y 200

Jugar con la biblioteca Volley, me di cuenta de que cuando se hace un POST JsonObjectRequest , si el servidor devuelve un código 304 o 200 sin datos en la respuesta (response.data) , Volley lo interpreta como una respuesta de error, en lugar de un éxito.

Puedo solucionarlo agregando un par de líneas de código en el método Response<JSONObject> parseNetworkResponse(NetworkResponse response) en la clase 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)); } } 

¿Es la mejor solución para este problema?

¡Gracias!

EDITAR

Comprobando la clase BasicNetwork.java me di cuenta de que Volley comprueba si una respuesta no tiene datos preguntando si 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]; } 

Pero el problema sigue siendo la excepción JSONE que se produce cuando Volley intenta crear una nueva cadena con response.data == new byte[0] en el método parseNetworkResponse.

Miguel- ¿No se llama este método solo si es una respuesta de éxito?

Para todos los códigos de estado <200 o código de estado> 200 volley invoca parseNetworkError (VolleyError volleyError) en lugar del método parseNetworkResponse (NetworkResponse response). Mira aquí –

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

Número de línea -118-120

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

Y el bloque de captura correspondiente Número de línea – 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); } } 

Si desea anular este comportamiento, puede agregar su implementación específica de código de estado dentro del método BasicNetwork.java-> performRequest.

Editar: Así que no es debido al código de estado, sino debido a la respuesta vacía. Bueno, creo que está haciendo lo correcto implementando su clase de solicitud personalizada. Volley viene con algunos tipos populares predefinidos de solicitudes de facilidad de uso, pero siempre puedes crear tu propio. En lugar de una implementación basada en código de estado, preferiría simplemente comprobar si la siguiente cadena está vacía antes de deserializarla:

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

** no han probado esto, pero usted consigue el punto 🙂

  • Cómo obtener el código de estado en la respuesta correcta Volley Android
  • Cómo comunicarse desde php a Android
  • Android enviando solicitudes de correos a django servidor csrf fallando
  • Hacer solicitud de volley en diferentes hilos
  • Android Volley + JSONObjectRequest Almacenamiento en caché
  • Android Volley hace 2 peticiones al servidor cuando la política de reintento se establece en 0
  • Android usb requestWait no volver
  • Android - cancelar solicitud de voleibol
  • Android Volley almacena peticiones cuando está fuera de línea
  • Facebook cómo enviar solicitud de autorización de solicitud a los amigos?
  • Android: comprueba si la solicitud es GET o POST
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.