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

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

具体分析:

        首先解释下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.             

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 anIllegalStateException. 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引擎的缓冲区(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内置对象!) 。
时间: 2024-10-21 03:46:46

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

android java.lang.IllegalStateException异常产生的原因及解决办法 Offending field: mSpans

String lience=chepai_short.getText().toString()+chepai_number.getText().toString(); openmap.put("lience",lience.toString()); openmap.put("UserName", tv_username.getText().toString()); openmap.put("cardtype",tv_cardtype.getTex

Android开发中java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: java.lang.NullPointerException 错误的集中原因及解决办法

上面那个问题刚解决,就又来一个问题~~~~ 错误信息字符串:java.lang.RuntimeException: Unable to start activity ComponentInfo{...}: java.lang.NullPointerException 网上有不少解决办法 一般都会在Activity  onCreate()方法里的setContentView(XXX)发生此错误,网上查阅了很多原因,大概有四种重要可能的原因: 原因一:xxx的错误,若为R.layout.main 

关于 java 上传,下载和导入报java.lang.IllegalStateException异常解决办法

java.lang.IllegalStateException异常解决办法 最近在使用response.sendRedirect()时出现如下错误:java.lang.IllegalStateException            org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:423) 经过分析.查看jdk文档终于找到解决的办法,在response.sendRedirect()方法后加

response.sendRedirect 报 java.lang.IllegalStateException 异常的解决思路

今天在进行代码开发的时候,出现了 java.lang.IllegalStateException异常,response.sendRedirect("./DEFAULT.html"); 这一条语句出错. 在网上进行查找之后,发现问题很有可能是因为response.sendRedirect方法执行了两次,其中一次肯定是项目框架里面的跳转,而我自己要进行跳转的话,就显得极其不方便,最后我把目光放到前端页面,在前端页面进行跳转. 一开始我的前端语句是:window.location.href=

遇到java.lang.IllegalThreadStateException: Thread already started. 错误的解决办法

通过单击事件开启线程时,再次单击就会出现 java.lang.IllegalThreadStateException: Thread already started. 错误 解决办法: 创建一个Runnable: Runnable DownloadRunnable = new Runnable() { @Override public void run() { //需要处理操作} 然后每次需要调用的时候会重新new一个Thread: new Thread(DownloadRunnable).st

批量下载的实现及java.lang.IllegalStateException异常

在工作流的一张表单里可能会有多个步骤上传附件,在用户的待办中往往会存在多条带有附件的任务,如果一一打开并且点击下载链接下载,不仅费时,而且繁琐,用户体验较差. OA系统采用的是FastDFS做为文件服务器,FastDFS的Java客户端提供了上传.下载等功能供调用. 在我之前的文章里对此有描述,目前已有的代码有对文件的批量上传功能,但下载的参数往往是针对单个文件.比如单个文件的下载方法如下: /**  * 文件下载  * @author chao.gao  * @date 2014-2-17 下

【Servlet+Struts2】文件下载时抛出java.lang.IllegalStateException异常的解决方法

java.lang.IllegalStateException这种异常,不代表文件不能下载,不代表程序写错,它在Tomcat抛出完异常之后依然能够正常运行的.只是看着不爽而已,每次下载都要在Tomcat抛出一大堆异常. java.lang.IllegalStateException主要是用了后台把文件丢进respond的缓冲区,然后respond再把下载的文件扔回JSP的情况所造成的.Servlet与Struts2反正是JSP都有可能存在.其主要原因JSP在对缓冲区读,后台JAVA在对缓冲写所导

java.lang.IllegalStateException异常:简单的分析和简单解决方案

我们在做文件上传或者下载,或者过滤等操作时,可能要用到页面的输出流. 例如在action中使用: response.reset(); response.setContentType(”application/vnd.ms-excel”); OutputStream os = response.getOutputStream(); 抛出异常:java.lang.IllegalStateException 原因分析: 这是web容器生成的servlet代码中有out.write(””),这个和JSP

关于java.lang.NoSuchMethodError: android.widget.RelativeLayout.setBackground的解决办法

今天用一个安卓4.0.4版本的手机测试手上的项目,发现logcat弹出这样一个提示“java.lang.NoSuchMethodError: android.widget.RelativeLayout.setBackground”,然后这个页面因为没有做异常捕获处理,所以直接导致系统崩溃了.检查后发现里面设置背景用的是setBackground()方法,而该方法是API16才开始有的.遇到这样的情况,将这个方法更改为setBackgroundDrawable()就可以了.