The reason getOutputStream () has already been called for this response anomalies and solutions

1. In jsp appear under tomcat6.0 getOutputStream () has already been called for this response causes of abnormal and solutions

  This error occurs in tomcat6.0 jsp generally are used in the jsp output stream (such as the output image verification code, file downloading, etc.), does not properly handle a good reason.

  Specific reason:
  in the jsp tomcat after compiling into a servlet in function _jspService (HttpServletRequest request, HttpServletResponse response) last there is a code like

1 finally {
2       if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
3 }

  Here is the release of objects used in the jsp, calls response.getWriter (), because this method is and response.getOutputStream () conflict! So there will be more than the exception.

  Then of course, is to propose solutions, in fact, quite simple (and not some friends put it - all spaces and carriage return symbols for all within the jsp are deleted), call the following two after you are finished using the output stream lines of code:

1 out.clear();
2 out = pageContext.pushBody();

Why add two sentences it?

out.clear ();  

out = pageContext.pushBody (); 
Copy the code out = pageContext.pushBody (); What does this mean? Why not join the abnormal, they reported: java.lang.IllegalStateException: getOutputStream () has already  been called for this response
copy the code 
role first of all you need to know pushBody () is out to save the current object and updates the PageContext Out in the Page range object. As to why you want to add this sentence, because the JSP container after processing the request method calls releasePageConter release all PageContestObject, and call getWriter methods simultaneously. Since the conflict getWriter methods related to the use in the JSP page flow getOutputStream method, it will cause this anomaly, the solution is to the upper floors of the same, only the final with these two statements in the JSP page. out.clear (); 

OUT = pageContext.pushBody (); 
duplicated code




   Here is a final output color codes Examples (examples of this almost everywhere)

 imag.jsp

 1  <%@ page import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
 2  <%@ page import="java.io.OutputStream" %>
 3  <%!
 4    Color getRandColor(int fc,int bc){
 5      Random random = new Random();
 6      if(fc>255) fc=255;
 7      if(bc>255) bc=255;
 8      int r=fc+random.nextInt(bc-fc);
 9      int g=fc+random.nextInt(bc-fc);
10      int b=fc+random.nextInt(bc-fc);
11      return new Color(r,g,b);
12    }
13  %>
14  <%
15    try{
16      response.setHeader("Pragma","No-cache");
17      response.setHeader("Cache-Control","no-cache");
18      response.setDateHeader("Expires", 0);
19      int width=60, height=20;
20      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
21      OutputStream os=response.getOutputStream();
22      Graphics g = image.getGraphics();
23      Random random = new Random();
24      g.setColor(getRandColor(200,250));
25      g.fillRect(0, 0, width, height);
26  
27      g.setFont(new Font("Times New Roman",Font.PLAIN,18));
28      g.setColor(getRandColor(160,200));
29      for (int i=0;i<155;i++){
30        int x = random.nextInt(width);
31        int y = random.nextInt(height);
32        int xl = random.nextInt(12);
33        int yl = random.nextInt(12);
34        g.drawLine(x,y,x+xl,y+yl);
35      }
36      String sRand="";
37      for (int j=0;j<4;j++){
38        String rand=String.valueOf(random.nextInt(10));
39        sRand+=rand;
40        g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
41        g.drawString(rand,13*j+6,16);
42      }
43      session.setAttribute("rand",sRand);
44      g.dispose();
45  
46      ImageIO.write(image, "JPEG",os);
47      os.flush();
48      os.close();
49      os=null;
50      response.flushBuffer();
51      out.clear();
52      out = pageContext.pushBody();
53    }catch(IllegalStateException e){
54       System.out.println(e.getMessage());
55      e.printStackTrace();
56    }
57   %>

  如有不足之处,欢迎斧正!

2.getOutputStream() has already been called for this response问题的解决
  在jsp向页面输出图片的时候,使用response.getOutputStream()会有这样的提示:java.lang.IllegalStateException:getOutputStream() has already been called for this response,会抛出Exception

  原因一:
  JSP默认的输出流为PrintWriter ,即<% %>以外的东西所默认的输出方式,如果你尝试在JSP中使用ServletOutputStream就会引起错误.要嘛直接改用Servlet输出(复写service方法),要嘛删除除%><%中的任何东西(包括HTML标签,空格,回车等东西)应该就可以。对于这样的情况应该这样来解决,删除%><%之间的所有内容包括空格和换行符,最后也要消除空格和换行符,最好再加上一句response.reset()。
  原因二:     
  在J2EE的API参考里有这么个:

  ServletResponse的getWriter()方法里会抛出这个异常:

    IllegalStateException - if the getOutputStream method has already been called for this response object

  而它的getOutputStream()方法里会抛出这个异常:

    IllegalStateException - if the getOutputStream method has already been called for this response object

  并且两者的函数申明里都有这么样的一句
    Either this method or getOutputStream() may be called to write the body, not both.
    Either this method or getWriter() may be called to write the body, not both.


  以上说明也解释了为什么在往页面中写入图片的时候要使用如下循环格式
  OutputStream output=response.getOutputStream();
  while((len=in.read(b)) >0) {
    output.write(b,0,len); 
  }
output.flush();
而不是把response.getOutputStream().write()放到循环体内

在页面中直接写:
<body bgcolor="#ffffff">
<h1>
<%
response.getOutputStream();
%>
</h1>
</body>
将会出现错误消息如下:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
org.apache.catalina.connector.Response.getWriter(Response.java:604)
org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)

发布了90 篇原创文章 · 获赞 21 · 访问量 47万+

Guess you like

Origin blog.csdn.net/yx13649017813/article/details/44810195