Java,MalformedChunkCodingException

标签 java android apache http

我有一个 Android 应用程序给我这个异常:

org.apache.http.MalformedChunkCodingException: CRLF expected at end of chunk

此方法抛出异常:(目的是将从服务器收到的响应写到文件中。)

public static void getResponseBodyForServerData(
    final HttpEntity entity) throws IOException, ParseException {

    if (entity == null) {
        throw new IllegalArgumentException("HTTP entity may not be null");
    }
    InputStream instream = entity.getContent();

    if (instream == null) {
        return;
    }
    File file = new File(Environment.getExternalStorageDirectory() + 
        "/foo/Response.txt");

    if (!file.exists()) {
        file.createNewFile();
    }
    OutputStream out = new FileOutputStream(file);
    byte buf[] = new byte[1024];
    int len;
    while ((len = instream.read(buf)) > 0)
        out.write(buf, 0, len);
    out.flush();
    out.close();
}

于是我将上面的代码修改为:

public static void getResponseBodyForServerData(
    final HttpEntity entity) throws IOException, ParseException {

    if (entity == null) {
        throw new IllegalArgumentException("HTTP entity may not be null");
    }
    InputStream instream = entity.getContent();
    InputStreamReader inputStreamReader = new InputStreamReader(
        instream, "UNICODE") ;

    if (instream == null) {
        return;
    }
    File file = new File(Environment.getExternalStorageDirectory() + 
        "/foo/Response.txt");
    if (!file.exists()) {
        file.createNewFile();
    }

    BufferedReader bufferedReader = new BufferedReader(inputStreamReader) ;
    BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(
        new FileOutputStream(file),"UNICODE")) ;

    String singleLine = null ;

    while((singleLine = bufferedReader.readLine()) != null) {
        bufferedWriter.write(singleLine) ;
    }

    bufferedWriter.flush() ;
    bufferedWriter.close() ;
}

然后代码就可以运行了,是什么导致了这个错误,原始代码有什么问题?

最佳答案

我看到这个问题很老了,但是当我搜索 MalformedChunkCodingException 时它出现了。所以这里有一些提示。

我只能猜测您的问题是什么,因为您没有告诉我们异常发生在哪一行以及您使用的是哪个版本的 org.apache.http.HttpEntity。

第一个 MalformedChunkCodingException: CRLF expected at end of chunk 确实是问题所在。 当你有一个 chunked http transfer 时它就会发生并且至少有一个 \r\n 在该传输中丢失。

有两种可能的错误。首先服务器不发送它们或客户端丢失它们。

检查服务器是否正常,检查请求响应是否正常。例如,您可以使用 curl 查看十六进制的响应:

curl -ivs --raw http://host:port/somePath/toResource --trace /dev/stdout

这是一些示例输出:

00a0: 30 31 22 7d 5d 0d 0a 30 0d 0a 0d 0a             01"}]..0....

在输出中看到 \r\n0d 0a 了吗? 这意味着服务器实际上发送了正确的消息。

因此您在阅读响应时可能丢失了一些字节。

我使用调试器并为 MalformedChunkCodingException(Eclipse 中的 Java 异常断点)设置了一个断点。我查看了第一次处理传入响应的堆栈,实际上缓冲区中只有一半的响应。

分块消息是流式消息。所以可能是您在 InputStream 读取完整消息之前关闭了套接字。 例如,这发生在 jersey apache connector 中。 .

他们有这个代码:

return new FilterInputStream(inputStream) {
    @Override
    public void close() throws IOException {
        response.close();
        super.close();
    }

哪个失败了:

JulijanasJezov on 18 Oct 2016

This change does not work with the org.apache.httpcomponents: httpclient: 4.5.1+ when using chunked transfer encoding. This is because they have changed the way they close the connection.

In this case when response.close() is called the connection is closed and the input stream's buffer is cleared, then super.close() function is not able to close the ChunkedInputStream and results in org.apache.http.ConnectionClosedException: Premature end of chunk coded message body: closing chunk expected.

The reason of the exception occurring is that upon close of ChunkedInputStream, the close() function reads the remainder of the chunked message and it fails because the buffer of the stream has been cleared when the connection has been closed in response.close() call. Reference: https://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/ChunkedInputStream.html#close()

The fix to this problem is putting super.close() line of code before the response.close(). This allows for the stream to be closed correctly before its buffer has been cleared.

当我发现在我们的项目中使用了不兼容版本的jersey-apache-connector时,我的问题就解决了(旧)和 http-client (新)在我们的 maven pom. (Depenency Hierachy 表示:httpclient:4.5.3(从 4.5 管理)(因与 4.5.3 冲突而省略))

关于Java,MalformedChunkCodingException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8635112/

相关文章:

java - 存在 UI 线程问题的竞争条件。

java - python 中的 org.apache.commons.lang.StringEscapeUtils

php - 让 htaccess 忽略部分网址

node.js - 在 Apache 下的子文件夹中运行的 Node 应用程序

java - Java中方程 "i+++++i"的计算顺序是什么?

java - 从 LinkedList 库更改为自定义类

java - org.apache.struts.action.ActionMessage 无法转换为 org.apache.struts.action.ActionError

java - 给定一个 obj-c 无符号字节数组,如何在 Java 中获得等效的字节值?

com.jobyab.controllers.registerController.doPost 处的 java.lang.NullPointerException

java - 使用 Android 连接到 Neo4J