如何将生成的Buffered映像从Servlet传递给响应?

时间:2015-07-08 11:49:24

标签: java servlets web httpresponse bufferedimage

在我的Servlet中,我生成了一个BufferedImage:

BufferedImage bgImage = createImage();

我保存了它:

saveImage(bgImg, getImageSaveDir() + IMAGE_NAME);

之后,我想将其返回到在浏览器中显示的响应。

我尝试将图片发送到回复:

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();
}

但我收到一个例外:

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
  

将生成的Buffered映像从Servlet传递到响应并在浏览器中显示它的最佳方法是什么?

我试过这个:

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();

现在没有出现异常,但代码仍然不起作用:(

1 个答案:

答案 0 :(得分:1)

请参阅以下代码org.apache.catalina.connector.OutputBuffer.realWriteBytes,这是异常的来源。

    // 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);
        }
    }

现在注意说明

的例外中的评论
  

写入时的IOException几乎总是由远程客户端引起的   中止请求。

对我而言,您的浏览器与服务器之间存在一些连接问题。可能连接断了。

现在可能有多种原因导致HTTP连接断开连接,例如:

  • 请求响应时间太长,因此Web服务器根据HTTP超时超时请求。
  • 请求已从客户端终止。
  • 您发送了一些客户端无法理解的内容或不可接受的MIME类型,因此当Web服务器尝试提交响应时,出现错误。

对于Weblogic,如果我从浏览器启动服务器事务,然后在服务器响应之前关闭浏览器,那么在提交响应时,WL将抛出异常。
在您的情况下,根异常是IOException,但它被包装到ClientAbortException以在日志控制台上有意义。

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)

所以,你可能想: