java.lang.IllegalStateException:getOutputStream() has already been called for this response的解決方法


 

《輕量級J2EE企業應用實戰》一書的第2章有一個使用SerlvetResponse輸出圖像的例子,代碼如下:

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

%>


在Tomcat下運行時拋出如下異常:

      at org.apache.catalina.connector.Response.getWriter(Response.java:601)
     at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:196)
     ..................
    at org.apache.jsp.pages.drawImage_jsp._jspService(drawImage_jsp.java:84)
     at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98).
      ...............

查看轉換后的JSP代碼,發現第84行如下(綠色高亮處):
finally {
      
if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
     }

   }

我們看到在JSP頁面釋放資源的時候,調用了ServetResponse.getWriter()方法,之后程序即拋出異常了,查看Servlet的API發現問題:

public java.io.PrintWriter getWriter()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 - if the getOutputStream method has already been called for this response object
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屬性的內容

 

具體異常出錯信息如下:

 java.lang.IllegalStateException: getOutputStream() has already been called for this response
 at org.apache.catalina.connector.Response.getWriter(Response.java:607)
 at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:196)
 at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
 at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
 at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:179)
 at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:116)
 at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:76)
 at org.apache.jsp.jsp.notify.do_005fdownload_jsp._jspService(do_005fdownload_jsp.java:88)
 at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
 at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
 at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
 at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
 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.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
 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.http11.Http11Processor.process(Http11Processor.java:874)
 at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
 at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
 at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
 at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
 at java.lang.Thread.run(Thread.java:595)


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com