做一个下载模块,用的Servlet进行通信,前台使用了a标签调用Servlet,测试点击下载,弹出保存路径选择的时候,点确定或者取消,会触发下面的异常,百思不得其解。还在debug当中
错误信息:
org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:410)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:349)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:435)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:423)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91)
[INFO][http-bio-8080-exec-5][2017-12-27 17:14:34][com.yfy.customQuery.commons.ServletDownload] - java.net.SocketException: Connection reset by peer: socket write error
at com.yfy.customQuery.commons.ServletDownload.doGet(ServletDownload.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
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:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:216)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:487)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:373)
at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:239)
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:119)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
at org.apache.coyote.Response.doWrite(Response.java:506)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:405)
... 27 more

解决方案 »

  1.   

    at com.yfy.customQuery.commons.ServletDownload.doGet(ServletDownload.java:62)    代码
      

  2.   

    package com.yfy.customQuery.commons;import lombok.extern.log4j.Log4j;import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;import java.io.*;
    import java.net.URLEncoder;/**
     * ServletDownload类:
     * Servlet的实现类,继承HttpServlet类
     * 用于下载功能,当页面的<a>标签被触发时,根据href路径调用此方法,弹出下载路径选择框
     */
    @Log4j
    @WebServlet(name = "ServletDownload")
    public class ServletDownload extends HttpServlet {    private static final long serialVersionUID = 1L;    public ServletDownload() {
            super();
        }    protected void doPost(HttpServletRequest v_Request, HttpServletResponse v_Response) throws ServletException, IOException {    }    protected void doGet(HttpServletRequest v_Request, HttpServletResponse v_Response) throws ServletException, IOException {
            //创建输入流、输出流
            InputStream l_InputStream = null;
            OutputStream l_OutputStream = null;
            try {
                v_Request.setCharacterEncoding("UTF-8");
                //获得请求文件名
                String l_FileName = v_Request.getParameter("fileName");
                String l_EncodeFileName;
                //处理文件名有中文问题
                if (v_Request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
                    l_EncodeFileName= URLEncoder.encode(l_FileName,"UTF-8");
                } else {
                    l_EncodeFileName= new String(l_FileName.getBytes(),"ISO-8859-1");
                }
                //设置Content-Disposition,最后加双引号处理名称中间有空格问题
                v_Response.addHeader("Content-Disposition","attachment;filename=\""+l_EncodeFileName+"\"");
                //设置文件MIME类型
                v_Response.setContentType(getServletContext().getMimeType(l_FileName));
                //获取目标文件的绝对路径
                String l_FullFileName = getServletContext().getRealPath("/download/" + l_FileName);
                //读取文件
                l_InputStream = new FileInputStream(l_FullFileName);
                l_OutputStream = v_Response.getOutputStream();
                //写文件
                //8192代表每次读取的最大字节数位8192个字节,读取后的l_Buff存放在缓存中
                byte[] l_Buff = new byte[8192];
                int l_BytesRead;
                while (-1 != (l_BytesRead = l_InputStream.read(l_Buff, 0, l_Buff.length))) {
                    l_OutputStream.write(l_Buff, 0, l_BytesRead);
                }
                //不管是否下载成功,都删除服务器端创建的文件
                File l_File = new File(l_FullFileName);
                if (l_File.delete()){
                    log.info(l_File.getName()+"文件删除成功");
                }else {
                    l_File.deleteOnExit();
                }
            }catch (Exception v_Exception){
                v_Exception.printStackTrace();
                log.info(v_Exception.getMessage());
            } finally {
                if(l_InputStream!=null){
                    l_InputStream.close();
                }
                if(l_OutputStream!=null){
                    l_OutputStream.close();
                }
            }
        }
    }
      

  3.   

    package com.yfy.customQuery.commons;import lombok.extern.log4j.Log4j;import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;import java.io.*;
    import java.net.URLEncoder;/**
     * ServletDownload类:
     * Servlet的实现类,继承HttpServlet类
     * 用于下载功能,当页面的<a>标签被触发时,根据href路径调用此方法,弹出下载路径选择框
     */
    @Log4j
    @WebServlet(name = "ServletDownload")
    public class ServletDownload extends HttpServlet {    private static final long serialVersionUID = 1L;    public ServletDownload() {
            super();
        }    protected void doPost(HttpServletRequest v_Request, HttpServletResponse v_Response) throws ServletException, IOException {    }    protected void doGet(HttpServletRequest v_Request, HttpServletResponse v_Response) throws ServletException, IOException {
            //创建输入流、输出流
            InputStream l_InputStream = null;
            OutputStream l_OutputStream = null;
            try {
                v_Request.setCharacterEncoding("UTF-8");
                //获得请求文件名
                String l_FileName = v_Request.getParameter("fileName");
                String l_EncodeFileName;
                //处理文件名有中文问题
                if (v_Request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
                    l_EncodeFileName= URLEncoder.encode(l_FileName,"UTF-8");
                } else {
                    l_EncodeFileName= new String(l_FileName.getBytes(),"ISO-8859-1");
                }
                //设置Content-Disposition,最后加双引号处理名称中间有空格问题
                v_Response.addHeader("Content-Disposition","attachment;filename=\""+l_EncodeFileName+"\"");
                //设置文件MIME类型
                v_Response.setContentType(getServletContext().getMimeType(l_FileName));
                //获取目标文件的绝对路径
                String l_FullFileName = getServletContext().getRealPath("/download/" + l_FileName);
                //读取文件
                l_InputStream = new FileInputStream(l_FullFileName);
                l_OutputStream = v_Response.getOutputStream();
                //写文件
                //8192代表每次读取的最大字节数位8192个字节,读取后的l_Buff存放在缓存中
                byte[] l_Buff = new byte[8192];
                int l_BytesRead;
                while (-1 != (l_BytesRead = l_InputStream.read(l_Buff, 0, l_Buff.length))) {
                    l_OutputStream.write(l_Buff, 0, l_BytesRead);
                }
                //不管是否下载成功,都删除服务器端创建的文件
                File l_File = new File(l_FullFileName);
                if (l_File.delete()){
                    log.info(l_File.getName()+"文件删除成功");
                }else {
                    l_File.deleteOnExit();
                }
            }catch (Exception v_Exception){
                v_Exception.printStackTrace();
                log.info(v_Exception.getMessage());
            } finally {
                if(l_InputStream!=null){
                    l_InputStream.close();
                }
                if(l_OutputStream!=null){
                    l_OutputStream.close();
                }
            }
        }
    }
      

  4.   

    引起该异常的原因有两个:1,如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。2,一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的。