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
.
- Obtención de solicitud de contenido corporal mediante el método POST de Retrofit 2.0
- ¿Apoya Android varias solicitudes HTTP al mismo tiempo?
- Enviando una solicitud POST con JSONArray usando Volley
- Uso de la biblioteca AQuery con la solicitud PUT y StringEntity (String)
- Los anuncios de Google con varios tamaños de anuncio de DFP dan error
@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.
- ¿Hay alguna manera de cambiar el System User Agent de Genymotion Emulator?
- Problema con la solicitud de Facebook en Android
- Interceptar solicitudes POST en un WebView
- Android - Volley RequestFuture Timeout
- Android httprequest java.net.UnknownHostException
- Http obtener solicitud en Android
- Android envía la solicitud de correos https al servidor sin métodos desaconsejados
- Phonegap y prompt ()
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í –
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 🙂
- Uso de ShapeDrawable predeterminado en un StateListDrawable en Android 4.2
- Mantenimiento de un PhoneGap Hybrid / Web App Codebase