在我们做struts2文件下载的时候,经常会遇到这种问题:点“打开/保存”一切正常,但当我们点击“取消”时,却报一堆的异常,非常让人头疼,错误如下(每个人的错误估计不太一样,以我的为例):
2011-5-19 10:30:23 org.apache.catalina.core.ApplicationDispatcher invoke
严重: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:611)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:180)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:118)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:77)
at org.apache.jsp.layout.adminlayout_jsp._jspService(adminlayout_jsp.java:204)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:389)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
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.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:551)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:488)
at com.opensymphony.module.sitemesh.filter.PageFilter.writeDecorator(PageFilter.java:173)
at com.opensymphony.module.sitemesh.filter.PageFilter.applyDecorator(PageFilter.java:158)
at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:62)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:102)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:164)
at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:141)
at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:90)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:417)
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)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
异常原因分析:
[stream对应的类是org.apache.struts2.dispatcher.StreamResult,该类的处理过程如下:
1.配置其中result标签下的各个参数
2.从服务器中获取输入流,并同时与客户端建立输出流(服务器与客户端链接通过Socket进行连接)
3.当点击“保存”或“打开”时,开始传输数据。如果点击“取消”,关闭所有的流。
这里要注意的是,但是实际发现Socket并没有断开!并且流也没有关闭!这一点非常重要!
所以在JSP容器通过Response获取输出流之前,前面的流并没有关闭,所以会造成该异常的报出。
我在CSDN上搜了一个人的解决方法,他是这么解决的:
<package name="default" extends="json-default" namespace="/">
<!-- 定义全局Result -->
<global-results>
<result name="client-abort-exception">/null.jsp</result>
</global-results>
</package>
<package name="main" extends="default" namespace="/">
<action name="download" class="fileAction" method="download">
<exception-mapping result="client-abort-exception" exception="org.apache.catalina.connector.ClientAbortException"></exception-mapping>
<param name="savePath">/upload/download</param>
<!-- 文件下载配置结果类型为stream的结果 -->
<result name="download" type="stream">
<param name="inputName">targetFile</param>
<!-- 指定保存还是直接打开要下载的文件默认为:直接打开,这里配置保存 -->
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
<!-- 指定下载文件的缓存大小 -->
<param name="bufferSize">4096</param>
</result>
</action>
</package>
也就是说,如果抛出了ClientAbortException异常,那就跳转到“null.jsp”这个页面,这个页面中什么内容都没有。虽然这种方法暂时可行,但是当遇到其他异常的时候,也就是非ClientAbortException之后,这个方法就不可行了。我之前也是参照这种方法配置,但昨天我重新启动应用的时候,点击“取消”居然还报错,错误就是上面的一堆“java.lang.IllegalStateException”,而且这种方法也是一种逃避的方法,也就是置之不理。这并不可取,解决问题就要解决彻底明了,逃避是没用的,经过网上大师们的分析测试,最终解决办法如下:
1.下载一个插件struts2-sunspoter-stream-1.0.jar(附件中有下载)。
2.将附件解压获取struts2-sunspoter-stream-1.0.jar,并复制在/WEB-INF/lib下。
3.在原有的struts.xml的基础上进行相应的配置,配置如下:
<package name="main" extends="default" namespace="/">
<!-- 添加如下内容 -->
<result-types>
<result-type name="streamx" class="com.sunspoter.lib.web.struts2.dispatcher.StreamResultX"/>
</result-types>
<action name="download" class="fileAction" method="download">
<param name="savePath">/upload/download</param>
<!-- 文件下载配置结果类型为streamx -->
<result name="download" type="streamx">
<param name="inputName">targetFile</param>
<!-- 指定保存还是直接打开要下载的文件默认为:直接打开,这里配置保存 -->
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
<!-- 指定下载文件的缓存大小 -->
<param name="bufferSize">4096</param>
</result>
</action>
</package>
在这种方式下,只需添加一个result-type,将原有的result中type改为“streamx”,其他一律不变,在这种情况下,点击“取消”的同时也关闭了流,不会再报出该异常。
如果出现log4j的警告,比如:
21:23:44,676 WARN StreamResult:45 - StreamResultX Warn : socket write error
出现该警告说明正确执行,该警告说明,Socket非正常中断,但是流确实已经关闭,自此再也不用看到上面出现的讨厌异常结果。
分享到:
相关推荐
本篇将深入探讨Struts2下载取消报异常的解决方法,以及相关的知识点。 1. **Struts2 文件下载原理** - Struts2提供了方便的Action类和结果类型,如`StreamResult`,来处理文件下载。通过设置HTTP响应头,如`...
`Struts2 下载点取消报异常最终解决办法 - Angel_liu的日志 - 网易博客_files`目录可能包含与文章相关的其他资源。 总的来说,解决Struts2文件下载取消时的异常,关键在于正确管理和控制文件流,以及及时响应用户的...
在我们做struts2文件下载的时候,经常会遇到这种问题:点“打开/保存”一切正常,但当我们点击“取消”时,却报一堆的异常(其中包括ClientAbortException异常),非常让人头疼,如何彻底解决呢?附件中使用struts2-...
在struts2中使用result里type="stream"的结果类型时,可以实现文件的下载管理,使用时也是比较顺畅,但是当在“下载提示窗口”中点击“取消按钮”时,总是报出“java.lang.IllegalStateException”异常,异常内容...
总结来说,解决Struts2中下载取消报错问题的关键在于正确管理和控制文件流,确保在客户端取消下载时,服务器能够及时响应并终止操作。通过监控`ServletResponse`的状态和`ServletOutputStream`的关闭情况,可以有效...
在"struts2资源下载"中,我们可以获取到与Struts2相关的各种资料,包括但不限于教程、示例代码、API文档、安全补丁以及社区提供的插件等,这些都对学习和使用Struts2框架极其有益。 Struts2的核心功能包括: 1. **...
通过覆写StreamResult的方法 解决struts2文件下载点击取消服务器报错解
下面将详细讨论Struts2中的异常处理机制及其相关知识点。 1. **异常处理机制概述** Struts2提供了内置的异常处理机制,允许开发者定义全局和局部的异常映射,以控制应用程序中出现异常时的行为。全局异常处理适用...
Struts2作为一款流行的Java Web框架,其异常处理机制是其核心功能之一,它使得开发者能够优雅地管理和处理应用程序中的异常情况,提供了一种统一的错误处理方式,从而提高用户体验并增强程序的健壮性。 在Struts2...
此外,《Struts2权威指南》可能还会涵盖以下知识点: 1. **配置文件详解**:Struts2的配置主要通过struts.xml文件进行,包括动作配置、拦截器栈配置、全局结果等,熟悉配置语法对开发至关重要。 2. **OGNL(Object-...
### Struts2下载地址及相关知识点 #### 一、Struts2简介 Struts2是一个开源的Web应用框架,它继承了Struts1的设计理念,并在此基础上进行了大量的改进和完善。Struts2是Apache软件基金会下的一个顶级项目,它采用...
Struts2低版本安全漏洞及解决办法 Struts2低版本安全漏洞及解决办法
《Struts2权威指南》是李刚先生撰写的一本深入解析Struts2框架的专业书籍,其源代码的提供对于读者理解和实践Struts2框架具有极大的帮助。 源代码通常包含了书中讲解的各种示例和实战项目,使得学习者能够通过实际...
10. **异常处理**:Struts2提供了一套完整的异常处理机制,可以自定义错误页面和异常处理器。 总的来说,"struts2jar.zip"压缩包是一个实用的学习资源,涵盖了从基础到进阶的Struts2知识,通过阅读提供的说明和实践...
《Struts2技术内幕:深入解析Struts2架构设计与实现原理》以Struts2的源代码为依托,通过对Struts2的源代码的全面剖析深入探讨了Struts2的架构设计、实现原理、设计理念与设计哲学,对从宏观上和微观上去了解Struts2...
项目中出现的异常通常要用一个友好的异常页面来显示,通过对struts2.xml的配置能拦截全局异常,只要出现异常就会转向异常页面。
在Struts2中实现下载功能是一项常见的需求,这通常涉及到处理文件流并将其发送到客户端。以下是如何在Struts2中实现下载功能的详细步骤: 1. **Struts2配置**: 在Struts2的配置文件(例如struts.xml或类似的配置...
### Struts2乱码终极解决办法 #### 一、引言 在开发基于Struts2框架的应用时,经常遇到的一个问题就是中文乱码。这不仅影响用户体验,还可能导致数据处理错误。本文将详细介绍如何彻底解决Struts2中的乱码问题,并...
总之,Struts2文件上传和下载是Web开发中必不可少的功能,涉及的技术点包括表单处理、文件流操作、服务器配置以及错误处理。通过理解和实践提供的源代码,开发者可以加深对Struts2框架的理解,提升其在实际项目中的...
Struts2权威指南 带目录索引完整版