java.lang.IllegalStateException异常产生的原因及解决办法

问题描述:

152812_7SGX_3442347.png

错误原因:

       该异常表示,当前对客户端的响应已经结束,不能在响应已经结束(或说消亡)后再向 客户端(实际上是缓冲区)输出任何内容。

具体分析:

      首先解释下flush(),我们知道在使用读写流的时候数据先被读入内存这个缓冲区中,然后再写入文件,但是当数据读完时不代表数据已经写入文件完毕,因为可能还有一部分仍未写入文件而留在内存中,这时调用flush()方法就会把缓冲区的数据强行清空输出,因此flush()的作用就是保证缓存清空输出。

     response是服务端对客户端请求的一个响应,其中封装了响应头、状态码、内容等,服务端在把response提交到客户端之前,会向缓冲区内写入响应头和状态码,然后将所有内容flush。这就标志着该次响应已经committed(提交)。对于当前页面中 已经committed(提交)的response,就不能再使用这个response向缓冲区写任何东西(注:同一个页面中的response.XXX()是同一个response的不同方法,只要其中一个已经导致了committed,那么其它类似方式的调用都会导致 IllegalStateException异常)。

       【注意】能够导致响应已经committed的操作包括:forward, redirect, flushBuffer

JDK API:

153101_p3QD_3442347.png

 ②

153125_zKF0_3442347.png

③  

153154_OOjT_3442347.png

备    注:

 在一次响应commit之前,所有的内容输出都将写入servlet引擎的缓冲区(tomcat或weblogic的内容空间), 而在commit之后,上一次response向缓冲区写入的内容,将清空。由于servlet在没有设置单线程的情况下(使用Single-Threaded Model,servlet实现 SingleThreadModel接口,jsp使用<%@ page isThreadSafe="false" %>),是多线程的,所以上面所说的缓冲区,都将是该response所属的线程私有的内存空间。有了这个概念, 将可以分析碰到的关于servlet多线程的很多问题。如果不能确认response是否已经committed. 可以调用response.isCommitted()来判断。导致这个错误最普遍的原因是,jsp有编译错误。

常见解决办法:

         ①在response.sendRedirect()方法后加return语句即可,如下:
                       response.sendRedirect("login.jsp");
                       return;
         ②检查提交的url是否有误。

         ③如果你的页面中用了清缓存代码response.flushbuffer();又用到了response.sendRedirect(url);你可以把response.flushbuffer();去掉,或者用JS的window.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内置对象!) 。

转载于:https://my.oschina.net/u/3442347/blog/1505310

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值