OkHttpClient响应206异常

时间:2018-11-27 12:04:40

标签: android http-headers okhttp

我正在使用OkHttpClient for android应用程序从服务器下载PDF文件,下载PDF文件时出现异常。

System.err: java.io.IOException: 206

这是响应元素:

Date: Tue, 27 Nov 2018 12:45:17 GMT
Server: Apache/2.4.23 (Win64) PHP/5.6.25
Last-Modified: Mon, 09 Jan 2017 16:06:27 GMT
ETag: "392a0c-545ab8ccd2dc8"
Accept-Ranges: bytes
Content-Length: 1
Content-Range: bytes 3746315-3746315/3746316
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/pdf
OkHttp-Sent-Millis: 1543322716318
OkHttp-Received-Millis: 1543322716467

这是用来下载文件的代码:

private final static int BUFFER_SIZE = 1024 * 8;
Request.Builder requestBuilder = new Request.Builder().url(itemUrl);

try {
        Response response = 
        getOkHttpClient().newCall(requestBuilder.build()).execute();

        long totalSize = response.body().contentLength();

        if (response.code() != 200) {
            throw new IOException(String.valueOf(response.code()));
        }

        RandomAccessFile out = new RandomAccessFile(tempItemFilePath, "rw");

        byte[] buffer = new byte[BUFFER_SIZE];

        BufferedInputStream in = new BufferedInputStream(response.body().byteStream(), BUFFER_SIZE);

        long bytesCount = 0;
        int bytesRead = 0;

        try {

            out.seek(out.length());

            while (true) {
                bytesRead = in.read(buffer, 0, BUFFER_SIZE);
                if (bytesRead == -1) {
                    break;
                }
                out.write(buffer, 0, bytesRead);
                manager.setDownloadStatus(magazine, ((bytesCount * 100) / totalSize));
                bytesCount += bytesRead;



                EventBus.getDefault().post(new DownloadStatusUpdateEvent());
            }
        } finally {
            out.close();
            if (in != null) {
                in.close();
            }
            in.close();
        }
        }

知道为什么它不起作用吗? PS:它适用于小于未下载文件的文件。

1 个答案:

答案 0 :(得分:0)

问题是您正在range request中请求构成响应的3746316字节中的最后一个字节。

作为回应,您将获得206状态码,根据RFC 7233:

  

206(部分内容)状态代码表示服务器处于      通过以下方式成功满足目标资源的范围请求      转移所选表示形式的一个或多个部分      对应于请求范围内的可满足范围      标头字段(第3.1节)。

出现该异常的原因是这段代码:

if (response.code() != 200) {
    throw new IOException(String.valueOf(response.code()));
}

您应该检查的是响应是否成功(即状态是否为2xx),可以通过以下方式完成:

if (!response.isSuccessful()) {
    throw new IOException(...);
}

请注意,尽管您的代码将成功创建一个包含响应内容的RandomAccessFile,即在这种情况下为单个字节,这可能不是故意的。