posts - 262,  comments - 221,  trackbacks - 0
          《輕量級(jí)J2EE企業(yè)應(yīng)用實(shí)戰(zhàn)》一書的第2章有一個(gè)使用SerlvetResponse輸出圖像的例子,代碼如下:

          <%
            BufferedImage image 
          = new BufferedImage(400400, 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" , 30080
          );
            g.drawString(
          "green:swim"300120
          );
            g.drawString(
          "blue:jump"300160
          );
            ImageIO.write(image, 
          "bmp"
          , response.getOutputStream());
            
          //
          out.clear();
            
          //out = pageContext.pushBody();

          %>

          在Tomcat下運(yùn)行時(shí)拋出如下異常:

              at org.apache.catalina.connector.Response.getWriter(Response.java:601)
              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:
          185
          )
              at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:
          116
          )
              at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:
          76
          )
              
          at org.apache.jsp.pages.drawImage_jsp._jspService(drawImage_jsp.java:84)
              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:
          328
          )
              at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:
          315
          )
              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:
          210
          )
              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:
          870
          )
              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:
          685
          )
              at java.lang.Thread.run(Thread.java:
          595)

          查看轉(zhuǎn)換后的JSP代碼,發(fā)現(xiàn)第84行如下(綠色高亮處):

            public void _jspService(HttpServletRequest request, HttpServletResponse response)
                  
          throws java.io.IOException, ServletException 
          {

              JspFactory _jspxFactory 
          = null
          ;
              PageContext pageContext 
          = null
          ;
              HttpSession session 
          = null
          ;
              ServletContext application 
          = null
          ;
              ServletConfig config 
          = null
          ;
              JspWriter out 
          = null
          ;
              Object page 
          = 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,
                            
          nulltrue8192true
          );
                _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(
          "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");

                out.write("<html>\n");
                out.write(
          "<head>\n"
          );
                out.write(
          "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"
          );
                out.write(
          "<title>Draw Image</title>\n"
          );
                out.write(
          "</head>\n"
          );
                out.write(
          "<body>\n"
          );
                out.write(
          "\r\n"
          );

            BufferedImage image 
          = new BufferedImage(400400
          , 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" , 30080
          );
            g.drawString(
          "green:swim"300120
          );
            g.drawString(
          "blue:jump"300160
          );
            ImageIO.write(image, 
          "bmp"
          , response.getOutputStream());
            
          //
          out.clear();
            
          //out = pageContext.pushBody();


                out.write(
          "\r\n");
                out.write(
          "</body>\n"
          );
                out.write(
          "</html>"
          );
              }
           catch (Throwable t) {
                
          if (!(t instanceof SkipPageException))
          {
                  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);
              }

            }

          我們看到在JSP頁(yè)面釋放資源的時(shí)候,調(diào)用了ServetResponse.getWriter()方法,之后程序即拋出異常了,查看Servlet的API發(fā)現(xiàn)問(wèn)題: 
          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()方法和該方法都有可能被調(diào)用,來(lái)輸出JSP頁(yè)面的內(nèi)容,如果其中的一個(gè)方法被調(diào)用了,再調(diào)用另一個(gè)方法就會(huì)拋出異常。

          解決方法如下:

          將JSP頁(yè)面的最后兩行代碼的注釋去掉,這兩行代碼的作用如下:

          out.clear():清空緩存的內(nèi)容。

          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

          ·返回一個(gè)新的BodyContent(代表一個(gè)HTML頁(yè)面的BODY部分內(nèi)容)
          ·保存JspWriter實(shí)例的對(duì)象out
          ·更新PageContext的out屬性的內(nèi)容



          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2008-01-19 22:24 Paul Lin 閱讀(43362) 評(píng)論(10)  編輯  收藏 所屬分類: J2EE基礎(chǔ)


          FeedBack:
          # re: getOutputStream() has already been called for this response的解決方法
          2008-08-19 20:02 | wasw100
          不錯(cuò),對(duì)jsp有了更深的理解了,收藏了  回復(fù)  更多評(píng)論
            
          # re: getOutputStream() has already been called for this response的解決方法
          2008-12-23 11:36 | 常青
          太感謝了。這個(gè)問(wèn)題郁悶了我們幾個(gè)月,后來(lái)還是改了設(shè)計(jì)給繞過(guò)去的。現(xiàn)在可以按照正常的設(shè)計(jì)修改代碼了。再次謝過(guò)了。  回復(fù)  更多評(píng)論
            
          # re: getOutputStream() has already been called for this response的解決方法
          2009-05-06 10:06 | dongzgguang
          非常感謝  回復(fù)  更多評(píng)論
            
          # re: getOutputStream() has already been called for this response的解決方法[未登錄](méi)
          2010-05-17 09:09 | Jordan
          謝謝啊!
          問(wèn)題解釋的很清楚, 解決方案也正確!
          希望以后多多交流, 我QQ914132900  回復(fù)  更多評(píng)論
            
          # re: getOutputStream() has already been called for this response的解決方法
          2010-07-19 11:32 | GAME OVER
          想問(wèn)下博主大哥,小弟也遇到了這個(gè)情況,但是在后面加了那兩句也不行!
          后來(lái)我也去看了下提示錯(cuò)誤生成的servlet文件,但是有一點(diǎn)不同的是我的只有這
          _jspxFactory.releasePageContext(_jspx_page_context);
          沒(méi)有前面的if語(yǔ)句,直接在生成servlet的文件中加if語(yǔ)句,但是刷新頁(yè)面還是會(huì)有異常的。實(shí)在不懂是怎么回事,只好想請(qǐng)教下大哥!
          小弟Email:ice-_-wind@163.com
          勞煩大哥看到了回復(fù)下!
            回復(fù)  更多評(píng)論
            
          # re: getOutputStream() has already been called for this response的解決方法[未登錄](méi)
          2010-11-27 17:37 | test
          錯(cuò)誤解決不了,我照你的做,還是一樣!!  回復(fù)  更多評(píng)論
            
          # re: getOutputStream() has already been called for this response的解決方法
          2011-04-06 20:21 | 沈林楠
          我內(nèi)牛滿面啊,郁悶我一天的問(wèn)題終于解決了,愛(ài)死你了  回復(fù)  更多評(píng)論
            
          # re: getOutputStream() has already been called for this response的解決方法
          2011-10-07 10:02 | 三等功
          我這樣用了還是不行啊
            回復(fù)  更多評(píng)論
            
          # re: getOutputStream() has already been called for this response的解決方法
          2013-09-17 13:31 | 冰凝火龍吟
          謝謝指點(diǎn)。。。。。。  回復(fù)  更多評(píng)論
            
          # re: getOutputStream() has already been called for this response的解決方法
          2014-01-07 14:52 | Hucc
          大家可以看下面的網(wǎng)頁(yè),我采用的是下面的方法。
          http://stackoverflow.com/questions/1776142/getoutputstream-has-already-been-called-for-this-response  回復(fù)  更多評(píng)論
            
          <2008年1月>
          303112345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點(diǎn)博客

          好友博客

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 马龙县| 集贤县| 文水县| 武邑县| 斗六市| 太保市| 衡东县| 东海县| 武安市| 靖安县| 佛坪县| 兴海县| 花垣县| 营山县| 遵义市| 从化市| 高青县| 长丰县| 宜兰市| 汉中市| 沐川县| 内黄县| 翁牛特旗| 上虞市| 巍山| 玉门市| 怀集县| 手机| 遂平县| 成安县| 固镇县| 会东县| 瑞丽市| 始兴县| 秀山| 寻甸| 鄂尔多斯市| 定兴县| 丹东市| 济宁市| 阜阳市|