Servlet IOException when streaming a Byte Array
- by MontyBongo
I occasionally get an IOException from a Servlet I have that writes a byte array to the outputstream in order to provide a file download capability.
This download servlet has a reasonable amount of traffic (100k hits a month) and this exception occurs rarely, around 1-2 times a month.
I have tried recreating the exception by using the exact same Base64 String and no exception is raised and the Servlet behaves as designed.
Is this IO Exception being caused by something outside my applications control? For example
a network issue or the user resetting the connection? I have tried to google the cause of an IOException at this point in the stack but to no avail.
The environment is running Tomcat 5.5 on CentOS 5.3 with an Apache HTTP Server acting as a proxy using 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)
And the code in the 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");
}
}