【发布时间】:2010-06-01 21:40:17
【问题描述】:
我偶尔会从我拥有的 Servlet 中收到一个 IOException,该 Servlet 将字节数组写入输出流以提供文件下载功能。
此下载 servlet 具有合理的流量(每月 10 万次点击),这种异常很少发生,大约每月 1-2 次。
我尝试使用完全相同的 Base64 字符串重新创建异常,并且没有引发异常并且 Servlet 的行为符合设计。
此 IO 异常是由我的应用程序无法控制的东西引起的吗?例如 网络问题或用户重置连接?我曾尝试在堆栈中搜索 IOException 的原因,但无济于事。
环境在 CentOS 5.3 上运行 Tomcat 5.5,Apache HTTP 服务器使用 proxy_ajp 作为代理。
ClientAbortException: java.io.IOException
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBufferjava:366)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:352)
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.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:83)
at com.myApp.Download.doPost(Download.java:34)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:691)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
at com.myApp.EntryServlet.service(EntryServlet.java:278)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at com.myApp.filters.RequestFilter.doFilter(RequestFilter.java:16)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:444)
at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:472)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1286)
at java.lang.Thread.run(Thread.java:636)
Caused by: java.io.IOException
at org.apache.coyote.ajp.AjpAprProcessor.flush(AjpAprProcessor.java:1200)
at org.apache.coyote.ajp.AjpAprProcessor$SocketOutputBuffer.doWrite(AjpAprProcessor.java:1285)
at org.apache.coyote.Response.doWrite(Response.java:560)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBufferjava:361)
以及Download Servlet中的代码:
@Override
protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException {
try {
response.setContentType("application/pdf");
response.setHeader("Pragma", "");
response.setHeader("Cache-Control", "");
response.setHeader("Content-Disposition", "Inline; Filename=myPDFFile..pdf");
ServletOutputStream out = response.getOutputStream();
byte[] downloadBytes = Base64.decode((String)request.getAttribute("fileToDownloadBase64"));
out.write(downloadBytes);
} catch (Base64DecodingException e) {
e.printStackTrace();
response.getOutputStream().print("An error occurred");
}
}
【问题讨论】: