您的位置:首页 > 编程语言 > PHP开发

厚积薄发————getOutputStream() has already been called for this response的解决方法

2011-07-25 12:53 561 查看
《轻量级J2EE企业应用实战》一书的第2章有一个使用SerlvetResponse输出图像的例子,代码如下:

<%
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属性的内容

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐