下载链接提前关闭

下载链接被提前关闭
org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 100,273,812; received: 51,420,928)

异常信息

org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 100,273,812; received: 51,420,928)
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:178)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135)
at java.util.zip.CheckedInputStream.read(CheckedInputStream.java:82)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at com.aliyun.oss.event.ProgressInputStream.read(ProgressInputStream.java:118)
at java.util.zip.CheckedInputStream.read(CheckedInputStream.java:82)
at java.io.FilterInputStream.read(FilterInputStream.java:107)

原因之一:

从字面意思上看是预期是要接受100,273,812字节,但实际只接收了51,420,928字节,待下载的消息体提前结束了;真实原因有很多种,比如:
a.两次读取数据间隔时间超过设置的超时时间,浏览器会关闭一段时间没有发送或接收数据的连接;
b. httpclient请求超时设置得太短,而服务端处理的时间太长,eg: 服务器处理耗时需要5秒,而客户端请求超时只有3秒;
c. 下载的过程中出现了其他异常,服务端主动关闭了流。

解决方案1:

针对上面出现的三种情况一般解决方案:

  1. 在下载时提前告诉浏览器文件待下载的大小,在流write之前,设置header的Content-Length,让浏览器保持链接可用
response.setContentLengthLong(fileSize);
  1. 设置httpclient的请求超时时间比服务端处理时间稍微大点
clientConfiguration.setConnectionTimeout(connectionTimeout);
 conf.setRequestTimeout(requestTimeout);
  1. 解决服务端出现的异常,文件流下载操作单独try-catch-finally
 byte[] buffer = new byte[1024];
            response.reset();
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            String fileName = HttpUtils.encodeAttachmentName(businessFileDO.getFileName(), request) ;
            response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
            response.setHeader("Accept-ranges", "bytes");
            // 放在流write之前
            //response.setHeader("Content-Length", String.valueOf(fileSize));
            response.setContentLengthLong(fileSize);
            try{
            outputStream = response.getOutputStream();
            while ((length = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, length);
                    }
                     outputStream.flush();
                }finlly{
            IOUtils.closeQuietly(outputStream);
            IOUtils.closeQuietly(inputStream);
}     
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值