java.lang.IllegalStateException异常产生的缘由及解决办法

java.lang.IllegalStateException异常产生的缘由及解决办法  

错误类型大体为如下几种:
java.lang.IllegalStateException
Cannot   forward   a   response   that   is   already   committed 
IllegalStateException:response already commited 
IllegalStateException:getOutputStream() has already been called for this request
…………
错误缘由:
  
该异常表示,当前对客户端的响应已经结束,不能在响应已经结束(或说消亡)后再向客户端(其实是缓冲区)输出任何内容。 java

具体分析: web

首先解释下flush(),咱们知道在使用读写流的时候数据先被读入内存这个缓冲区中, 而后再写入文件,可是当数据读完时不表明数据已经写入文件完毕,由于可能还有一部分仍未写入文件而留在内存中,这时调用flush()方法就会把缓冲区的数据强行清空输出,所以flush()的做用就是保证缓存清空输出。response是服务端对客户端请求的一个响应,其中封装了响应头、状态码、内容等,服务端在把response提交到客户端以前,会向缓冲区内写入响应头和状态码,而后将全部内容flush。这就标志着该次响应已经committed(提交)。对于当前页面中已经committed(提交)response,就不能再使用这个response向缓冲区写任何东西(注:同一个页面中的response.XXX()是同一个response的不一样方法,只要其中一个已经致使了committed,那么其它相似方式的调用都会致使 IllegalStateException异常)。

【注意】可以致使响应已经committed的操做包括:forward, redirect, flushBuffer
JDK API
缓存

①    flushBuffer
 public void flushBuffer()throws IOException
Forces any content in the buffer to be written to the client. A call to this method automatically commits the response, meaning the status code and headers will be written. tomcat

②       sendRedirect
 public void sendRedirect(String location)throws IOException
Sends a temporary redirect response to the client using the specified redirect location URL. This method can accept relative URLs; the servlet container must convert the relative URL to an absolute URL before sending the response to the client. If the location is relative without a leading '/' the container interprets it as relative to the current request URI. If the location is relative with a leading '/' the container interprets it as relative to the servlet container root.
If the response has already been committed, this method throws an IllegalStateException. After using this method, the response should be considered to be committed and should not be written to. 服务器

③    forward
public void forward(ServletRequest request,ServletResponse response) throws ServletException,IOException Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server. This method allows one servlet to do preliminary processing of a request and another resource to generate the response.
For a RequestDispatcher obtained via getRequestDispatcher(), the ServletRequest object has its path elements and parameters adjusted to match the path of the target resource.
forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward.
The request and response parameters must be either the same objects as were passed to the calling servlet's service method or be subclasses of the ServletRequestWrapper or ServletResponseWrapper classes that wrap them.
   注:注:在一次响应commit以前,全部的内容输出都将写入servlet引擎的缓冲区(tomcatweblogic的内容空间), 而在commit以后,上一次response向缓冲区写入的内容,将清空。因为servlet在没有设置单线程的状况下(使用Single-Threaded Modelservlet实现SingleThreadModel接口,jsp使用<%@ page isThreadSafe="false" %>),是多线程的,因此上面所说的缓冲区,都将是该response所属的线程私有的内存空间。有了这个概念,将能够分析碰到的关于servlet多线程的不少问题。若是不能确认response是否已经committed. 能够调用response.isCommitted()来判断。致使这个错误最广泛的缘由是,jsp有编译错误。
常看法决办法: 多线程

①    response.sendRedirect()方法后加return语句便可,以下: app

 response.sendRedirect("login.jsp"); jsp

 return; ide

②    查提交的url是否有误。 this

③若是你的页面中用了清缓存代码response.flushbuffer();又用到了response.sendRedirect(url);

你能够把response.flushbuffer();去掉,或者用JSwindow.location.href="url";来作转向。

④若是你用了OutputStream,而web容器生成的servlet代码中有out.write(””),这个和JSP中调用的
response.getOutputStream()
冲突。out.write()这个是字符流,而response.getOutputStream()是字节流,你不能在同一个页面中调用多个输出流。不管先调用哪个,在调用第二个时都会抛出IllegalStateException,由于在jsp中,out变量是经过response.getWriter获得的。在多个使用了 outputStream的<%%>语句之间不能有空格及多余的字符。也就是页面中除了使用了outputStream的<%%>以外不能有空格或其它任何字符,在以内的语句能够有空格及回车。

JSP页面作输出的时候有两种方式.一是经过JspWriter,另外一个是经过OutputStream,但两者互相排斥.若是并存的话就会报告以上异常.在不得不使用OutputStream的时候.咱们必需要把JspWriter舍弃掉了。找到请求异常的页面所对应的Servlet..把其中全部使用JspWriter的语句所有去掉.或者是到你的JSP文件里把动态输出的代码注释掉.这里注意换行和空格制表符均为JspWriter输出.应该一块儿去掉.保存文件从新启动服务器你会发现上述异常 消失了。
因为jsp container在处理完成请求后会调用releasePageContet方法释放所用的PageContext object,而且同时调用getWriter方法,因为getWriter方法与在jsp页面中使用流相关的getOutputStream方法冲突,因此会形成这种异常,解决办法是:只须要在jsp页面的最后加上两条语句:   

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

便可(其中out,pageContext均为jsp内置对象!)

相关文章
相关标签/搜索