最近写了一些接口提供给第三方对接,再做一层 nginx 代理出去,其中有这样两个接口,一个是文件上传接口,一个是文件下载接口,文件上传接口没有问题,但是文件下载接口一直报这个一下这个错误,用 postman 下载不是在转圈就是没有返回:
Caused by: java.io.IOException: Broken pipe
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:469)
at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:142)
at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:118)
at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:167)
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1360)
at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:718)
at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:538)
at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:482)
at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:632)
at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:127)
at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:229)
at org.apache.coyote.Response.doWrite(Response.java:614)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:358)
而我的主要代码是:
public void downloadFile(HttpServletResponse response, String filePath) {
try {
// 获取文件存入 inputStream 中,我们自己的业务
ServletOutputStream output = response.getOutputStream();
byte[] buffer = new byte[1024];
int len = inputStream.read(buffer);
while (len != -1) {
output.write(buffer, 0, len);
len = inputStream.read(buffer);
}
output.flush();
output.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("下载文件出错:" + e.getMessage());
}
return;
}
output.write(buffer, 0, len);
我一直以为是 response 断了,所以显示管道断开的异常,因为这个项目是部署在 tomcat9 服务器上,所以我往 tomcat 方面百度了很久,也没找到问题,接着我修改了代码,修改 inputStream 写入 response 代码,以为是缺少了什么细节,不仅还是报异常,有时候还多了下面这个错误:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:371)
at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:845)
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:750)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:406)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:384)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
这让我抓狂,最后请教了我的大佬同事,开始他的思路跟我一样,也是以为是写入问题,最后我们想起我们还做了 nginx 代理,想着去看一下 nginx 日志,发现还真的有问题, nginx 的 error.log 日志报了这个错误:
upstream sent invalid chunked response while reading upstream
然后我们就终于找到了问题的所在了,原来是代码没问题,但是 nginx 转发的时候出问题了,百度后发现是需要再 nginx 的 location 模块里面配置 proxy_http_version 1.1
原因是 nginx 在代理是默认 http 版本为 1.0,由于文件的下载需要使用功能分块传递,但 http1.0 是不支持这个特性的,所以 nginx 需要配置为 1.1 版本, 否则无法进行转发。但我看到其他服务没有配置这个项目也可以转发下载,我就很奇怪了。
原文地址:https://blog.csdn.net/weixin_43726137/article/details/129104575
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_9837.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!