`
zxt1985
  • 浏览: 21318 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Struts2 下载点取消报异常最终解决办法

阅读更多
在我们做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非正常中断,但是流确实已经关闭,自此再也不用看到上面出现的讨厌异常结果。
1
4
分享到:
评论
4 楼 w156445045 2012-05-31  
神罗天征 写道
请教楼主:这个jar包是否存在struts2的版本不兼容问题,我用的struts2.1.8出现java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class com.sunspoter.lib.web.struts2.dispatcher.StreamResultX)

您好,我也出现这个问题呢,

请问这个问题您解决了嘛?谢谢~盼望回复~
3 楼 zxt1985 2011-09-17  
神罗天征 写道
请教楼主:这个jar包是否存在struts2的版本不兼容问题,我用的struts2.1.8出现java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class com.sunspoter.lib.web.struts2.dispatcher.StreamResultX)


十分抱歉,因为工作忙,很久没来博客了,这个包没有版本兼容问题,因为我用的也是struts2.1.8,可能你少加了其他包吧?
2 楼 神罗天征 2011-08-23  
请教楼主:这个jar包是否存在struts2的版本不兼容问题,我用的struts2.1.8出现java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class com.sunspoter.lib.web.struts2.dispatcher.StreamResultX)
1 楼 vincegod 2011-08-04  
非常感谢你的解决方案啊~~~

相关推荐

    Struts2 下载取消报异常最终解决办法

    本篇将深入探讨Struts2下载取消报异常的解决方法,以及相关的知识点。 1. **Struts2 文件下载原理** - Struts2提供了方便的Action类和结果类型,如`StreamResult`,来处理文件下载。通过设置HTTP响应头,如`...

    Struts中 下载时点击取消异常解决包

    `Struts2 下载点取消报异常最终解决办法 - Angel_liu的日志 - 网易博客_files`目录可能包含与文章相关的其他资源。 总的来说,解决Struts2文件下载取消时的异常,关键在于正确管理和控制文件流,以及及时响应用户的...

    Struts2下载文件点击取消出现的异常解决办法(含demo)

    在我们做struts2文件下载的时候,经常会遇到这种问题:点“打开/保存”一切正常,但当我们点击“取消”时,却报一堆的异常(其中包括ClientAbortException异常),非常让人头疼,如何彻底解决呢?附件中使用struts2-...

    解决struts2下载异常的jar包 struts2-sunspoter-stream-1.0.jar

    在struts2中使用result里type="stream"的结果类型时,可以实现文件的下载管理,使用时也是比较顺畅,但是当在“下载提示窗口”中点击“取消按钮”时,总是报出“java.lang.IllegalStateException”异常,异常内容...

    解决Struts2中下载文件时点击取消按钮后台报错问题

    总结来说,解决Struts2中下载取消报错问题的关键在于正确管理和控制文件流,确保在客户端取消下载时,服务器能够及时响应并终止操作。通过监控`ServletResponse`的状态和`ServletOutputStream`的关闭情况,可以有效...

    struts2资源下载,struts2资源下载

    在"struts2资源下载"中,我们可以获取到与Struts2相关的各种资料,包括但不限于教程、示例代码、API文档、安全补丁以及社区提供的插件等,这些都对学习和使用Struts2框架极其有益。 Struts2的核心功能包括: 1. **...

    struts2文件下载点击取消服务器报错解决办法

    通过覆写StreamResult的方法 解决struts2文件下载点击取消服务器报错解

    Struts2之异常处理案例struts003

    下面将详细讨论Struts2中的异常处理机制及其相关知识点。 1. **异常处理机制概述** Struts2提供了内置的异常处理机制,允许开发者定义全局和局部的异常映射,以控制应用程序中出现异常时的行为。全局异常处理适用...

    Struts2异常处理机制

    Struts2作为一款流行的Java Web框架,其异常处理机制是其核心功能之一,它使得开发者能够优雅地管理和处理应用程序中的异常情况,提供了一种统一的错误处理方式,从而提高用户体验并增强程序的健壮性。 在Struts2...

    Struts2权威指南 加源码

    此外,《Struts2权威指南》可能还会涵盖以下知识点: 1. **配置文件详解**:Struts2的配置主要通过struts.xml文件进行,包括动作配置、拦截器栈配置、全局结果等,熟悉配置语法对开发至关重要。 2. **OGNL(Object-...

    struts2下载地址

    ### Struts2下载地址及相关知识点 #### 一、Struts2简介 Struts2是一个开源的Web应用框架,它继承了Struts1的设计理念,并在此基础上进行了大量的改进和完善。Struts2是Apache软件基金会下的一个顶级项目,它采用...

    Struts2低版本安全漏洞及解决办法

    Struts2低版本安全漏洞及解决办法 Struts2低版本安全漏洞及解决办法

    struts2权威指南源代码

    《Struts2权威指南》是李刚先生撰写的一本深入解析Struts2框架的专业书籍,其源代码的提供对于读者理解和实践Struts2框架具有极大的帮助。 源代码通常包含了书中讲解的各种示例和实战项目,使得学习者能够通过实际...

    struts2jar.zip

    10. **异常处理**:Struts2提供了一套完整的异常处理机制,可以自定义错误页面和异常处理器。 总的来说,"struts2jar.zip"压缩包是一个实用的学习资源,涵盖了从基础到进阶的Struts2知识,通过阅读提供的说明和实践...

    struts2技术内幕+struts2权威指南

    《Struts2技术内幕:深入解析Struts2架构设计与实现原理》以Struts2的源代码为依托,通过对Struts2的源代码的全面剖析深入探讨了Struts2的架构设计、实现原理、设计理念与设计哲学,对从宏观上和微观上去了解Struts2...

    struts2处理项目全局异常

    项目中出现的异常通常要用一个友好的异常页面来显示,通过对struts2.xml的配置能拦截全局异常,只要出现异常就会转向异常页面。

    struts2下载功能实现

    在Struts2中实现下载功能是一项常见的需求,这通常涉及到处理文件流并将其发送到客户端。以下是如何在Struts2中实现下载功能的详细步骤: 1. **Struts2配置**: 在Struts2的配置文件(例如struts.xml或类似的配置...

    Struts2乱码终极解决办法

    ### Struts2乱码终极解决办法 #### 一、引言 在开发基于Struts2框架的应用时,经常遇到的一个问题就是中文乱码。这不仅影响用户体验,还可能导致数据处理错误。本文将详细介绍如何彻底解决Struts2中的乱码问题,并...

    struts2文件上传下载源代码

    总之,Struts2文件上传和下载是Web开发中必不可少的功能,涉及的技术点包括表单处理、文件流操作、服务器配置以及错误处理。通过理解和实践提供的源代码,开发者可以加深对Struts2框架的理解,提升其在实际项目中的...

    Struts2权威指南-带目录索引完整版.pdf

    Struts2权威指南 带目录索引完整版

Global site tag (gtag.js) - Google Analytics