您现在的位置是:首页 > 正文

java.lang.IllegalStateException错误原因以及解决方法

2023-11-06 15:36:44阅读 547
Servlet.service() for servlet default threw exception
java.lang.IllegalStateException
    at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:407)
    at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:725)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:483)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at filters.TomcatFormFilter_UTF8.doFilter(TomcatFormFilter_UTF8.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)

错误原因

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

这是web容器生成的servlet代码中有out.write(””),这个和JSP中调用的response.getOutputStream()产生冲突.即Servlet规范说明,不能既调用 response.getOutputStream(),又调用response.getWriter(),无论先调用哪一个,在调用第二个时候应会抛出 IllegalStateException,因为在jsp中,out变量是通过response.getWriter得到的,在程序中既用了response.getOutputStream,又用了out变量,故出现以上错误.

具体分析

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

解决:

法一:在JSP文件中,加入下面两句

<%
out.clear();
out = pageContext.pushBody();
%>

其中out,pageContext均为jsp内置对象!

此法的缺陷:
很多开发项目并不是JSP前端,如freemarker,velocity等
造成问题的"response.getOutputStream()"并未被写在JSP里,而是写在servlet/action里.

法二: 在struts2的action中,不要return 回具体的result文件,而是return null

//return SUCCESS;
 return null;


文章来源:https://blog.csdn.net/zls_12/article/details/21157601
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:https://www.dflian.com/981.html

网站文章

  • 国产化Kettle、JDK、MySQL下载安装操作步骤

    国产化Kettle、JDK、MySQL下载安装操作步骤

    Kettle、JDK、MySQL下载安装操作步骤

    2023-11-06 15:36:33
  • vscode终端 因为在此系统上禁止运行脚本问题的解决方法

    vscode终端 因为在此系统上禁止运行脚本问题的解决方法

    错误提示: vue : 无法加载文件 E:\node\hao\node_modules.bin\vue.ps1,因为在此系统上禁止运行脚本。 解决方法: 方法1、在VScode控制台修改权限以管理员身份打开VScode, 并执行 Set-ExecutionPolicy RemoteSigned 方法2、在cmd执行相同的语句Set-ExecutionPolicy RemoteSigned,并...

    2023-11-06 15:36:21
  • 进阶JAVA篇-深入了解 Set 系列集合

    进阶JAVA篇-深入了解 Set 系列集合

    Set 类是 Java 中的一个集合类,它实现了 Set 接口。Set 是一个不允许包含重复元素的集合,它是通过哈希表实现的,不保证元素的顺序。HashSet 是 Java 中的一个集合类,它实现了 ...

    2023-11-06 15:36:18
  • 保姆级教学——集群环境搭建及创建集群

    保姆级教学——集群环境搭建及创建集群

    集群环境搭建及集群配置

    2023-11-06 15:36:09
  • react 怎么获取表格_React - 获取form表单数据

    ---------------------分割线-------------------------import React,{forwardRef,Ref,UseRef} from &#39;reac...

    2023-11-06 15:36:04
  • win 下重启mysql数据库的命令

    如果你使用的是 Windows 系统,你可以使用以下命令来重启 MySQL 数据库: 先停止 MySQL 服务: net stop mysql 然后再启动 MySQL 服务: net start mysql 需要注意的是,这两条命令需要在命令提示符中运行,并且需要管理员权限。 ...

    2023-11-06 15:35:59
  • chatgpt赋能python:Python断线重连完全指南:从原理到实现 最新发布

    断线重连是一项非常重要的网络编程技术。Python提供了socket模块来方便地实现这项功能。通过socket模块,可以简单地建立网络连接,并实现不间断的数据传输。本文介绍了断线重连的原理和Pytho...

    2023-11-06 15:35:55
  • IDEA提示不兼容类型,找不到合适的方法,无法推断类型变量,不适用等编译错误解决方法

    IDEA提示不兼容类型,找不到合适的方法,无法推断类型变量,不适用等编译错误解决方法

    这个针对和使用eclipse的小伙伴在代码交互上可能会存在在使用idea编译的时候报错,但是eclipse的小伙伴上并没有编译错误. 这是因为这个虽然是maven项目 但是Eclipse编译代码使用的是Eclipse自带的JDT(Java Development Tools) 而IDEA 这里默认使用的是JAVA_HONE中的javac javac相对JDT的检查机制来说,更加的严格,...

    2023-11-06 15:35:47
  • 善领云狗服务器维护中,善领云狗服务器维护中

    善领云狗服务器维护中,善领云狗服务器维护中

    善领云狗服务器维护中 内容精选换一换不支持直接加载外接硬件设备(如USB设备、银行U key、外接硬盘、加密狗等)。不支持带外管理,您的裸金属服务器资源统一由华为云管理和维护。不支持热迁移,服务器故障...

    2023-11-06 15:35:44
  • JavaScrip的DOM接口

    JavaScrip的DOM接口

    JavaScript的DOM(Document Object Model)是一种接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。DOM是一种将HTML或XML文档表示为对象树的标准方式。...

    2023-11-06 15:35:42