Reputation: 955
In my Servlet I generate a BufferedImage:
BufferedImage bgImage = createImage();
and I save it:
saveImage(bgImg, getImageSaveDir() + IMAGE_NAME);
After that I want to return it to the response to show in a browser.
I tried to send the image to the response:
File imageFile = new File(getImageSaveDir() + IMAGE_NAME);
response.setContentType("image/png");
BufferedImage bufferedImg = ImageIO.read(imageFile);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bufferedImg, "png", out);
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
But I receive an Exception:
ClientAbortException: java.net.SocketException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:369)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:448)
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:318)
at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:296)
at org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:98)
at javax.imageio.stream.FileCacheImageOutputStream.close(FileCacheImageOutputStream.java:238)
at javax.imageio.ImageIO.write(ImageIO.java:1580)
at tv.clever.xml.TeamImageProcessor.process(TeamImageProcessor.java:157)
at tv.clever.api.ApiServlet.doProcessing(ApiServlet.java:458)
at tv.clever.api.ApiServlet.process(ApiServlet.java:219)
at tv.clever.api.ApiServlet.doPost(ApiServlet.java:98)
at tv.clever.api.ApiServlet.doGet(ApiServlet.java:86)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at tv.clever.utils.messageresource.UTF8EncodingFilter.doFilter(UTF8EncodingFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at tv.clever.utils.security.URLFilter.doFilter(URLFilter.java:50)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at tv.clever.utils.security.CrossScriptingFilter.doFilter(CrossScriptingFilter.java:38)
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.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:470)
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:620)
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: Broken pipe
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.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:124)
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)
... 39 more
What is the best way to pass the generated Buffered image from Servlet to the response and display it in the browser?
I've tried this:
BufferedImage originalImage = ImageIO.read(new File(getImageSaveDir() + IMAGE_NAME));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(originalImage, "png", baos);
baos.flush();
byte[] imageInByte = baos.toByteArray();
baos.close();
response.setContentType("image/png");
response.setContentLength(imageInByte.length);
ServletOutputStream servletoutputstream = response.getOutputStream();
servletoutputstream.write(imageInByte);
servletoutputstream.flush();
Now the Exception does not appear, but the code still doesn't work:(
Upvotes: 1
Views: 2916
Reputation: 14658
See the below code of org.apache.catalina.connector.OutputBuffer.realWriteBytes
which is where the exception is coming.
// If we really have something to write
if (cnt > 0) {
// real write to the adapter
outputChunk.setBytes(buf, off, cnt);
try {
coyoteResponse.doWrite(outputChunk);
} catch (IOException e) {
// An IOException on a write is almost always due to
// the remote client aborting the request. Wrap this
// so that it can be handled better by the error dispatcher.
throw new ClientAbortException(e);
}
}
Now notice the comment in the exception which says
An IOException on a write is almost always due to the remote client aborting the request.
To me, it looks like some connection problem between your browser and server. Probably the connection is broken.
Now there could be multiple reasons for HTTP connection getting disconnected, like:
In case of Weblogic, if I initiate a server transaction from browser, and then close the browser before server could respond, then while commiting the response, WL will throw below exception.
In your case as well root exception is IOException
but it is wrapped to ClientAbortException
to be meaningful on log console.
java.io.IOException: An established connection was aborted by the software in your host machine
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
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:487)
So, you may want to:
ServletOutputStream#write()
Upvotes: 1