getOutputStream() has already been called for this response的解决方法

喜欢ヅ旅行 2022-08-20 06:09 276阅读 0赞

《轻量级J2EE企业应用实战》一书的第2章有一个使用SerlvetResponse输出图像的例子,代码如下:

None.gif<%
None.gif BufferedImage image = new BufferedImage(400, 400 , BufferedImage.TYPE_INT_RGB);
None.gif Graphics g = image.getGraphics();
None.gif g.fillRect(0,0,400,400 );
None.gif g.setColor(new Color(255,0,0 ));
None.gif g.fillArc(20,20,100,100,30,120 );
None.gif g.setColor(new Color(0,255,0 ));
None.gif g.fillArc(20,20,100,100,150,20 );
None.gif g.setColor(new Color(0,0,255 ));
None.gif g.fillArc(20,20,100,100,270,120 );
None.gif g.setColor(new Color(0,0,0 ));
None.gif g.drawString(“red:climb” , 300, 80 );
None.gif g.drawString(“green:swim”, 300, 120 );
None.gif g.drawString(“blue:jump”, 300, 160 );
None.gif ImageIO.write(image, “bmp” , response.getOutputStream());
None.gif // out.clear();
None.gif //out = pageContext.pushBody();
None.gif %>

在Tomcat下运行时抛出如下异常:

None.gif
None.gif at org.apache.catalina.connector.Response.getWriter(Response.java:601)
None.gif at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:196 )
None.gif at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125 )
None.gif at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118 )
None.gif at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:185 )
None.gif at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:116 )
None.gif at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:76 )
None.gif at org.apache.jsp.pages.drawImage_jsp._jspService(drawImage_jsp.java:84)
None.gif at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98 )
None.gif at javax.servlet.http.HttpServlet.service(HttpServlet.java:803 )
None.gif at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328 )
None.gif at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315 )
None.gif at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265 )
None.gif at javax.servlet.http.HttpServlet.service(HttpServlet.java:803 )
None.gif at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269 )
None.gif at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188 )
None.gif at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210 )
None.gif at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174 )
None.gif at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127 )
None.gif at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117 )
None.gif at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108 )
None.gif at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151 )
None.gif at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870 )
None.gif at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665 )
None.gif at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528 )
None.gif at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81 )
None.gif at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685 )
None.gif at java.lang.Thread.run(Thread.java:595)

查看转换后的JSP代码,发现第84行如下(绿色高亮处):

None.gif public void _jspService(HttpServletRequest request, HttpServletResponse response)
ExpandedBlockStart.gif throws java.io.IOException, ServletException {
InBlock.gif
InBlock.gif JspFactory _jspxFactory = null;
InBlock.gif PageContext pageContext = null;
InBlock.gif HttpSession session = null;
InBlock.gif ServletContext application = null;
InBlock.gif ServletConfig config = null;
InBlock.gif JspWriter out = null;
InBlock.gif Object page = this;
InBlock.gif JspWriter _jspx_out = null;
InBlock.gif PageContext _jspx_page_context = null;
InBlock.gif
InBlock.gif
ExpandedSubBlockStart.gif try {
InBlock.gif _jspxFactory = JspFactory.getDefaultFactory();
InBlock.gif response.setContentType(“text/html; charset=UTF-8”);
InBlock.gif pageContext = _jspxFactory.getPageContext(this, request, response,
InBlock.gif null, true, 8192, true);
InBlock.gif _jspx_page_context = pageContext;
InBlock.gif application = pageContext.getServletContext();
InBlock.gif config = pageContext.getServletConfig();
InBlock.gif session = pageContext.getSession();
InBlock.gif out = pageContext.getOut();
InBlock.gif _jspx_out = out;
InBlock.gif
InBlock.gif out.write(“\r\n”);
InBlock.gif out.write(“\n”);
InBlock.gif out.write(“<!DOCTYPE html PUBLIC \“-//W3C//DTD HTML 4.01 Transitional//EN\“ \“http://www.w3.org/TR/html4/loose.dtd\\">\\n“);
InBlock.gif out.write(“\n”);
InBlock.gif out.write(“\n”);
InBlock.gif out.write(“\n”);
InBlock.gif out.write(“Draw Image\n”);
InBlock.gif out.write(“\n”);
InBlock.gif out.write(“\n”);
InBlock.gif out.write(“\r\n”);
InBlock.gif
InBlock.gif BufferedImage image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
InBlock.gif Graphics g = image.getGraphics();
InBlock.gif g.fillRect(0,0,400,400);
InBlock.gif g.setColor(new Color(255,0,0));
InBlock.gif g.fillArc(20,20,100,100,30,120);
InBlock.gif g.setColor(new Color(0,255,0));
InBlock.gif g.fillArc(20,20,100,100,150,20);
InBlock.gif g.setColor(new Color(0,0,255));
InBlock.gif g.fillArc(20,20,100,100,270,120);
InBlock.gif g.setColor(new Color(0,0,0));
InBlock.gif g.drawString(“red:climb” , 300, 80);
InBlock.gif g.drawString(“green:swim”, 300, 120);
InBlock.gif g.drawString(“blue:jump”, 300, 160);
InBlock.gif ImageIO.write(image, “bmp”, response.getOutputStream());
InBlock.gif //out.clear();
InBlock.gif //out = pageContext.pushBody();
InBlock.gif
InBlock.gif out.write(“\r\n”);
InBlock.gif out.write(“\n”);
InBlock.gif out.write(““);
ExpandedSubBlockStart.gif } catch (Throwable t) {
ExpandedSubBlockStart.gif if (!(t instanceof SkipPageException)){
InBlock.gif out = _jspx_out;
InBlock.gif if (out != null && out.getBufferSize() != 0)
InBlock.gif out.clearBuffer();
InBlock.gif if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
ExpandedSubBlockEnd.gif }
ExpandedSubBlockStart.gif } finally {
InBlock.gif if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
ExpandedSubBlockEnd.gif }
ExpandedBlockEnd.gif }

我们看到在JSP页面释放资源的时候,调用了ServetResponse.getWriter()方法,之后程序即抛出异常了,查看Servlet的API发现问题:

  1. public java.io.PrintWriter getWriter()
  2. throws java.io.IOException

Returns a PrintWriter object that can send character text to the client. The PrintWriter uses the character encoding returned by getCharacterEncoding(). If the response’s character encoding has not been specified as described in getCharacterEncoding (i.e., the method just returns the default value ISO-8859-1), getWriter updates it to ISO-8859-1.

Calling flush() on the PrintWriter commits the response.

Either this method or getOutputStream() may be called to write the body, not both.

Returns:

a PrintWriter object that can return character data to the client

Throws:

UnsupportedEncodingException - if the character encoding returned by getCharacterEncoding cannot be used

java.lang.IllegalStateException

java.io.IOException - if an input or output exception occurred

See Also:

getOutputStream(), setCharacterEncoding(java.lang.String)

如API所言,由于ServletResponse.getOutputStream()方法和该方法都有可能被调用,来输出JSP页面的内容,如果其中的一个方法被调用了,再调用另一个方法就会抛出异常。

解决方法如下:

将JSP页面的最后两行代码的注释去掉,这两行代码的作用如下:

out.clear():清空缓存的内容。

pageContext.pushBody():参考API

public BodyContent pushBody ()

Return a new BodyContent object, save the current “out” JspWriter, and update the value of the “out” attribute in the page scope attribute namespace of the PageContext.

Returns:

the new BodyContent

·返回一个新的BodyContent(代表一个HTML页面的BODY部分内容)
·保存JspWriter实例的对象out
·更新PageContext的out属性的内容

发表评论

表情:
评论列表 (有 0 条评论,276人围观)

还没有评论,来说两句吧...

相关阅读