厚积薄发————getOutputStream() has already been called for this response的解决方法
2011-07-25 12:53
561 查看
《轻量级J2EE企业应用实战》一书的第2章有一个使用SerlvetResponse输出图像的例子,代码如下:
.java:76)atorg.apache.jsp.pages.drawImage_jsp._jspService(drawImage_jsp.java:84)atorg.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)atjavax.servlet.http.HttpServlet.service(HttpServlet.java:803)atorg.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)atorg.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)atorg.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)atjavax.servlet.http.HttpServlet.service(HttpServlet.java:803)atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)atorg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)atorg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)atorg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)atorg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)atorg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)atorg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)atorg.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)atorg.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)atorg.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)atorg.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)atorg.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)atjava.lang.Thread.run(Thread.java:595)
我们看到在JSP页面释放资源的时候,调用了ServetResponse.getWriter()方法,之后程序即抛出异常了,查看Servlet的API发现问题:
[b][b][b]如API所言,由于ServletResponse.getOutputStream()方法和该方法都有可能被调用,来输出JSP页面的内容,如果其中的一个方法被调用了,再调用另一个方法就会抛出异常。[/b][/b][/b]
解决方法如下:
将JSP页面的最后两行代码的注释去掉,这两行代码的作用如下:
out.clear():清空缓存的内容。
pageContext.pushBody():参考API
<% BufferedImageimage=newBufferedImage(400,400,BufferedImage.TYPE_INT_RGB); Graphicsg=image.getGraphics(); g.fillRect(0,0,400,400); g.setColor(newColor(255,0,0)); g.fillArc(20,20,100,100,30,120); g.setColor(newColor(0,255,0)); g.fillArc(20,20,100,100,150,20); g.setColor(newColor(0,0,255)); g.fillArc(20,20,100,100,270,120); g.setColor(newColor(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下运行时抛出如下异常:
atorg.apache.catalina.connector.Response.getWriter(Response.java:601) atorg.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:196) atorg.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125) atorg.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118) atorg.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:185) atorg.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:116) atorg.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImplpublicvoid_jspService(HttpServletRequestrequest,HttpServletResponseresponse) throwsjava.io.IOException,ServletException{ JspFactory_jspxFactory=null; PageContextpageContext=null; HttpSessionsession=null; ServletContextapplication=null; ServletConfigconfig=null; JspWriterout=null; Objectpage=this; JspWriter_jspx_out=null; PageContext_jspx_page_context=null; try{ _jspxFactory=JspFactory.getDefaultFactory(); response.setContentType("text/html;charset=UTF-8"); pageContext=_jspxFactory.getPageContext(this,request,response, null,true,8192,true); _jspx_page_context=pageContext; application=pageContext.getServletContext(); config=pageContext.getServletConfig(); session=pageContext.getSession(); out=pageContext.getOut(); _jspx_out=out; out.write("\r\n"); out.write("\n"); out.write("<!DOCTYPEhtmlPUBLIC\"-//W3C//DTDHTML4.01Transitional//EN\"\"http://www.w3.org/TR/html4/loose.dtd\">\n"); out.write("<html>\n"); out.write("<head>\n"); out.write("<metahttp-equiv=\"Content-Type\"content=\"text/html;charset=UTF-8\">\n"); out.write("<title>DrawImage</title>\n"); out.write("</head>\n"); out.write("<body>\n"); out.write("\r\n"); BufferedImageimage=newBufferedImage(400,400,BufferedImage.TYPE_INT_RGB); Graphicsg=image.getGraphics(); g.fillRect(0,0,400,400); g.setColor(newColor(255,0,0)); g.fillArc(20,20,100,100,30,120); g.setColor(newColor(0,255,0)); g.fillArc(20,20,100,100,150,20); g.setColor(newColor(0,0,255)); g.fillArc(20,20,100,100,270,120); g.setColor(newColor(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(); out.write("\r\n"); out.write("</body>\n"); out.write("</html>"); }catch(Throwablet){ if(!(tinstanceofSkipPageException)){ out=_jspx_out; if(out!=null&&out.getBufferSize()!=0) out.clearBuffer(); if(_jspx_page_context!=null)_jspx_page_context.handlePageException(t); } }finally{ if(_jspxFactory!=null)_jspxFactory.releasePageContext(_jspx_page_context); } }
.java:76)atorg.apache.jsp.pages.drawImage_jsp._jspService(drawImage_jsp.java:84)atorg.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)atjavax.servlet.http.HttpServlet.service(HttpServlet.java:803)atorg.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)atorg.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)atorg.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)atjavax.servlet.http.HttpServlet.service(HttpServlet.java:803)atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)atorg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)atorg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)atorg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)atorg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)atorg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)atorg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)atorg.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)atorg.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)atorg.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)atorg.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)atorg.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)atjava.lang.Thread.run(Thread.java:595)
查看转换后的JSP代码,发现第84行如下
publicvoid_jspService(HttpServletRequestrequest,HttpServletResponseresponse) throwsjava.io.IOException,ServletException{ JspFactory_jspxFactory=null; PageContextpageContext=null; HttpSessionsession=null; ServletContextapplication=null; ServletConfigconfig=null; JspWriterout=null; Objectpage=this; JspWriter_jspx_out=null; PageContext_jspx_page_context=null; try{ _jspxFactory=JspFactory.getDefaultFactory(); response.setContentType("text/html;charset=UTF-8"); pageContext=_jspxFactory.getPageContext(this,request,response, null,true,8192,true); _jspx_page_context=pageContext; application=pageContext.getServletContext(); config=pageContext.getServletConfig(); session=pageContext.getSession(); out=pageContext.getOut(); _jspx_out=out; out.write("\r\n"); out.write("\n"); out.write("<!DOCTYPEhtmlPUBLIC\"-//W3C//DTDHTML4.01Transitional//EN\"\"http://www.w3.org/TR/html4/loose.dtd\">\n"); out.write("<html>\n"); out.write("<head>\n"); out.write("<metahttp-equiv=\"Content-Type\"content=\"text/html;charset=UTF-8\">\n"); out.write("<title>DrawImage</title>\n"); out.write("</head>\n"); out.write("<body>\n"); out.write("\r\n"); BufferedImageimage=newBufferedImage(400,400,BufferedImage.TYPE_INT_RGB); Graphicsg=image.getGraphics(); g.fillRect(0,0,400,400); g.setColor(newColor(255,0,0)); g.fillArc(20,20,100,100,30,120); g.setColor(newColor(0,255,0)); g.fillArc(20,20,100,100,150,20); g.setColor(newColor(0,0,255)); g.fillArc(20,20,100,100,270,120); g.setColor(newColor(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(); out.write("\r\n"); out.write("</body>\n"); out.write("</html>"); }catch(Throwablet){ if(!(tinstanceofSkipPageException)){ out=_jspx_out; if(out!=null&&out.getBufferSize()!=0) out.clearBuffer(); if(_jspx_page_context!=null)_jspx_page_context.handlePageException(t); } }finally{ if(_jspxFactory!=null)_jspxFactory.releasePageContext(_jspx_page_context); } }
publicjava.io.PrintWritergetWriter() throwsjava.io.IOException ReturnsaPrintWriterobjectthatcansendcharactertexttotheclient.ThePrintWriterusesthecharacterencodingreturnedbygetCharacterEncoding().Iftheresponse'scharacterencodinghasnotbeenspecifiedasdescribedingetCharacterEncoding(i.e.,themethodjustreturnsthedefaultvalueISO-8859-1),getWriterupdatesittoISO-8859-1. Callingflush()onthePrintWritercommitstheresponse. EitherthismethodorgetOutputStream()maybecalledtowritethebody,notboth. Returns: aPrintWriterobjectthatcanreturncharacterdatatotheclient Throws: UnsupportedEncodingException-ifthecharacterencodingreturnedbygetCharacterEncodingcannotbeused java.lang.IllegalStateException-ifthegetOutputStreammethodhasalreadybeencalledforthisresponseobject java.io.IOException-ifaninputoroutputexceptionoccurred SeeAlso: getOutputStream(),setCharacterEncoding(java.lang.String)
我们看到在JSP页面释放资源的时候,调用了ServetResponse.getWriter()方法,之后程序即抛出异常了,查看Servlet的API发现问题:
publicjava.io.PrintWritergetWriter() throwsjava.io.IOException ReturnsaPrintWriterobjectthatcansendcharactertexttotheclient.ThePrintWriterusesthecharacterencodingreturnedbygetCharacterEncoding().Iftheresponse'scharacterencodinghasnotbeenspecifiedasdescribedingetCharacterEncoding(i.e.,themethodjustreturnsthedefaultvalueISO-8859-1),getWriterupdatesittoISO-8859-1. Callingflush()onthePrintWritercommitstheresponse. EitherthismethodorgetOutputStream()maybecalledtowritethebody,notboth. Returns: aPrintWriterobjectthatcanreturncharacterdatatotheclient Throws: UnsupportedEncodingException-ifthecharacterencodingreturnedbygetCharacterEncodingcannotbeused java.lang.IllegalStateException-ifthegetOutputStreammethodhasalreadybeencalledforthisresponseobject java.io.IOException-ifaninputoroutputexceptionoccurred SeeAlso: getOutputStream(),setCharacterEncoding(java.lang.String)
[b][b][b]如API所言,由于ServletResponse.getOutputStream()方法和该方法都有可能被调用,来输出JSP页面的内容,如果其中的一个方法被调用了,再调用另一个方法就会抛出异常。[/b][/b][/b]
解决方法如下:
将JSP页面的最后两行代码的注释去掉,这两行代码的作用如下:
out.clear():清空缓存的内容。
pageContext.pushBody():参考API
publicBodyContentpushBody()
ReturnanewBodyContentobject,savethecurrent"out"JspWriter,andupdatethevalueofthe"out"attributeinthepagescopeattributenamespaceofthePageContext.
Returns:
thenewBodyContent
·返回一个新的BodyContent(代表一个HTML页面的BODY部分内容)
·保存JspWriter实例的对象out
·更新PageContext的out属性的内容
相关文章推荐
- getOutputStream() has already been called for this response异常的原因和解决方法[转]
- getOutputStream() has already been called for this response的解决方法
- struts2中getOutputStream() has already been called for this response异常解决方法
- getOutputStream() has already been called for this response的解决方法
- getOutputStream() has already been called for this response异常的原因和解决方法
- getOutputStream() has already been called for this response的解决方法
- 登录页面验证码的简单实现,以及getOutputStream() has already been called for this response异常的解决方法
- getOutputStream() has already been called for this response异常出现的原因和解决方法
- getOutputStream() has already been called for this response的解决方法
- getOutputStream() has already been called for this response异常的原因和解决方法
- 验证码 getOutputStream() has already been called for this response异常的原因和解决方法
- 验证码 getOutputStream() has already been called for this response异常的原因和解决方法
- getOutputStream() has already been called for this response异常的原因和解决方法
- getOutputStream() has already been called for this response异常出现的原因和解决方法
- getOutputStream() has already been called for this response异常的原因和解决方法
- getOutputStream() has already been called for this response解释以及解决方法
- getOutputStream() has already been called for this response的解决方法
- getOutputStream() has already been called for this response异常出现的原因和解决方法
- 验证码 getOutputStream() has already been called for this response异常的原因和解决方法
- getOutputStream() has already been called for this response异常的原因和解决方法