Java ClientAbortException无法理解修复

Java ClientAbortException无法理解修复,java,tomcat,Java,Tomcat,我有以下例外情况: Exception in writing file. null ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:369) at org.apache.tomcat.util.buf

我有以下例外情况:

Exception in writing file. null ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error
 at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:369)
 at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:448)
 at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:363)
 at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:392)
 at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:381)
 at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at com.gtnexus.page.servlet.HttpCachePolicyFilter.doFilter(HttpCachePolicyFilter.java:173)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:107)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
 at java.lang.Thread.run(Thread.java:745) Caused by: java.net.SocketException: Connection reset by peer: socket write error
 at java.net.SocketOutputStream.socketWrite0(Native Method)
 at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
 at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
 at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:761)
 at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:448)
 at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:363)
 at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:785)
 at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:127)
 at org.apache.coyote.http11.InternalOutputBuffer.doWrite(InternalOutputBuffer.java:598)
 at org.apache.coyote.Response.doWrite(Response.java:533)
 at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:364) ... 75 more
它发生在以下代码上:

private void returnFile(File file, OutputStream out) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            byte[] buf = new byte[4 * 1024]; 
            int bytesRead;
            while ((bytesRead = fis.read(buf)) != -1) {
                out.write(buf, 0, bytesRead);
            }
            out.flush();
        } catch (Exception e) {
            log.error("Exception in writing file. " + e.getMessage(), e);
        } finally {
            CloseUtils.close(fis, out);
        }
    }
OutputStream指的是ServletOutputStream,其中呈现了一个excel,奇怪的是,它的修复非常奇怪,我无法理解,下面是修复方法

private void returnFile(File file, OutputStream out) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            int bytesRead;
            byte[] buf = new byte[(int) file.length()];
            while ((bytesRead = fis.read(buf)) != -1) {
                out.write(buf, 0, bytesRead);
            }
            out.flush();
        } catch (Exception e) {
            log.error("Exception in writing file. " + e.getMessage(), e);
        } finally {
            CloseUtils.close(fis, out);
        }
    }
您可以看到,唯一的区别是在异常情况下使用4kb缓冲区,修复缓冲区大小与文件总长度本身的大小

现在,在使用缓冲区的大文件的情况下是有效的,我的问题是,发生了什么?我不明白这个问题的原因,也不明白这个问题的解决方法,只是我给出的,但我不明白它是如何工作的,为什么


有人能解释一下吗,这样我就可以更好地解释这种修复方法了?

你能试着在响应上设置内容长度标题吗,比如
setHeader(“content length”,“file.length()”)?我会尝试,虽然我现在不能尝试,但我想问一下,为什么会导致这个问题,在连接关闭或请求处理之前不应该确定内容的长度,因为这个问题在此之前肯定会出现,我想知道这会产生什么影响。如果这是原因,它每次都会给出这个异常,不是选择性的,也不是不一致的,但听起来像是一件需要尝试的事情,我会在检查后尽快回复。当然这只是一个猜测,但我会尝试,也许如果客户端知道它的大小,就可以防止它在获得所有块之前中止。@Vivek“我会在检查完后尽快回复。”我不确定是否不赞成它,因此会提示OP做出响应,但我想知道这个问题到底发生了什么?