博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java.lang.IllegalStateException异常产生的原因及解决办法
阅读量:7086 次
发布时间:2019-06-28

本文共 2086 字,大约阅读时间需要 6 分钟。

hot3.png

问题描述:

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

你可能感兴趣的文章
Html中table显示空单元格的方法及table标签属性总结
查看>>
WPF 获取文件运行目录
查看>>
使用emma对web工程进行测试覆盖率检查
查看>>
android activity生命周期
查看>>
距离和相似度度量[转]
查看>>
ADO.net DataTable 和Amazon SimpleDB的相互转换
查看>>
[JS2] JS是弱类型
查看>>
企业搜索引擎开发之连接器connector(二十四)
查看>>
数学图形(1.9)悬链线
查看>>
有上下界的网络流问题
查看>>
AspectJ获取方法注解的信息
查看>>
我就是一名房地产经纪人!不是中介,谁能明白我们呢?
查看>>
深入浅出SQL注入
查看>>
[翻译] EAColourfulProgressView
查看>>
获取泛型的class 反射
查看>>
input 获取当前id,name
查看>>
linux zip 命令详解
查看>>
BZOJ3834 : [Poi2014]Solar Panels
查看>>
探索 OpenStack 之(8):Neutron 深入探索之 OVS + GRE 之 完整网络流程 篇
查看>>
Android Animation学习笔记
查看>>