Me estoy dirigiendo a un servicio web REST desde Android 4.0 utilizando HttpsURLConnection
. Esto funciona bien a menos que intente POST
algo. Esta es la sección de código correspondiente:¿Cómo desactivo explícitamente el modo de transmisión por secuencias para las conexiones HTTP en Android?
connection.setDoOutput(true);
connection.setChunkedStreamingMode(0);
ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeObjectToStream(out, object);
byte[] array = out.toByteArray();
connection.getOutputStream().write(array, 0, array.length);
Esto desencadena la siguiente excepción:
java.net.HttpRetryException: Cannot retry streamed HTTP body
De depuración Me di cuenta de que el flujo de salida consigo a través de connection.getOuputStream()
es de tipo ChunkedOutputStream
y de la excavación en el código fuente de los androides Pensé que si una solicitud necesita ser reintentada (por la razón que sea), se activa con la excepción anterior, porque se da cuenta de que es no usando un RetryableOutputStream
que quiere allí.
La pregunta ahora es: ¿Cómo puedo hacer que mi HttpsURLConnection devuelva un RetryableOutputStream, o más bien, cómo puedo prevenir la codificación de solicitud fragmentada correctamente? Yo pensé hice que ya con setChunkedStreamingMode(0)
, pero parece que esto no es el caso ...
[editar]
No, la implementación de un java.net.HTTPUrlConnection
ignora el modo de transmisión de 0 o menor:
public void setChunkedStreamingMode(int chunkLength) {
[...]
if (chunkLength <= 0) {
this.chunkLength = HttpEngine.DEFAULT_CHUNK_LENGTH;
} else {
this.chunkLength = chunkLength;
}
}
En una nota relacionada: Creo que la razón _por qué_ que quiere una RetryableOutputStream en absoluto es porque hay una protección autenticación básica configurado en el servidor REST y el HttpURLConnectionImpl de Android parecen volver a intentar automáticamente una solicitud cuando recibe una respuesta 401 no autorizada. –