11

我的目标是使用 Android 4.0 的 REST Web 服务HttpsURLConnectionPOST除非我尝试做某事,否则这很好用。这是相关的代码部分:

   connection.setDoOutput(true);
   connection.setChunkedStreamingMode(0);

   ByteArrayOutputStream out = new ByteArrayOutputStream();
   serializeObjectToStream(out, object);
   byte[] array = out.toByteArray();
   connection.getOutputStream().write(array, 0, array.length);

这会引发以下异常:

   java.net.HttpRetryException: Cannot retry streamed HTTP body

通过调试,我意识到我通过的输出流connection.getOuputStream()是类型的ChunkedOutputStream,并且通过挖掘 Android 源代码,我发现如果需要重试请求(无论出于何种原因),它会触发上述异常,因为它发现它没有使用RetryableOutputStream它想要的 a 。

现在的问题是:如何让我的 HttpsURLConnection 返回这样的 RetryableOutputStream,或者更确切地说,如何正确防止分块请求编码?我以为我已经这样做了setChunkedStreamingMode(0),但显然情况并非如此......

[编辑]

不,实现java.net.HTTPUrlConnection忽略 0 或更低的流模式:

 public void setChunkedStreamingMode(int chunkLength) {
    [...]
    if (chunkLength <= 0) {
        this.chunkLength = HttpEngine.DEFAULT_CHUNK_LENGTH;
    } else {
        this.chunkLength = chunkLength;
    }
}
4

2 回答 2

12

无赖!解决方案是根本不从客户端代码调用setChunkedStreamingMode()(甚至)!setFixedStreamingMode()“-1”是 fixedLength 和 chunkedLength 的内部默认值,不能在客户端设置,因为设置一个低于或等于“0”的值会使其默认为HttpEngine.DEFAULT_CHUNK_LENGTH(或在固定流模式情况下引发异常)。

于 2012-08-27T12:12:40.623 回答
1

解决方案是设置一个Content-Length标头(可能由下一部分设置)并setFixedLengthStreamingMode使用您打算发送的适当长度的 POST 消息进行调用。

请参阅此 SO FAQ 中的“流媒体模式”部分:

使用 java.net.URLConnection 触发和处理 HTTP 请求

于 2012-08-29T23:52:04.700 回答