Struts2下载文件点击取消的异常处理

来源:互联网 发布:记事本软件哪个好 编辑:程序博客网 时间:2024/05/16 18:58

做了一个从数据库读取图片名称并将其下载的代码,分别在chrome和360浏览器上运行,当在下载框点击取消时就会出现org.apache.catalina.connector.ClientAbortException的异常,具体异常如下:

java.lang.IllegalStateException      at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:407)      at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:108)      at com.opensymphony.module.sitemesh.filter.PageResponseWrapper.sendError(PageResponseWrapper.java:176)      at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:108)      at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:770)      at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:505)      at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395

解决方案

1、失败方案1

刚开始,根据同事的建议,让我捕获这个异常并将异常打印,不再抛出,但是在捕获异常时却将程序搞得更为复杂,却没有实际解决问题。

2、失败方案2

分析错误报告,得出是因为取消之后输出流没有被关闭。于是,尝试去关闭输出流。第一次,直接在下载的InputStream return之前将其关闭,导致服务器启动直接报错。第二次开始寻找取消的时候触发的那个节点,可是也一筹莫展。就在这个时候,百度的搜索结果里出现了一个看似解决问题的结果,结果确实一页看似解决了问题,却乱七八糟的东西。后来抱着试一试的心态,点开了另一篇博客http://bear.conan.blog.163.com/blog/static/970124612013017113518929/,问题终于解决了。

3、成功方案:来自网易博客bear.conan的博客的解决方案

分析原因:
stream对应的类是org.apache.struts2.dispatcher.StreamResult,该类的处理过程如下:
1、配置其中result标签下的各个参数
2、从服务器中获取输入流,并同时与客户端建立输出流(服务器与客户端链接通过Socket进行连接)
3、当点击“保存”或“打开”时,开始传输数据。如果点击“取消”,关闭所有的流
 但是实际发现Socket并没有断开,并且流也没有关闭,所以在JSP容器通过Response获取输出流之前,前面的流并没有关闭,所以会造成该异常的报出

解决方法:

1、下载struts2-sunspoter-stream-1.0.jar,复制到WEB-INF/lib下
2、在原有的struts.xml的基础上进行相应的配置,如下:

<package name="e3itm" extends="struts-default">  <result-types>   <!-- 用于处理下载文件点击取消时报出异常问题 -->    <result-type name="streamx" class="com.sunspoter.lib.web.struts2.dispatcher.StreamResultX"></result-type>  </result-types>   <action name="download" class="com.DownloadAction">                   <result name="success" type="streamx">                   <param name="inputName">download</param>                   <param name="bufferSize">4096</param>                   <param name="contentDisposition">filename=""</param>                   <param name="contentCharSet">UTF-8</param>               </result>     </action>  </package>

添加了 < result-type > …… < /result-type >片段,并在原有的action 下的 result 中type改为“streamx”

如果是使用注解方式同样如下:
@Result(type=”streamx”, params={“inputName”,”inputStream”,”bufferSize”,”4096”, “contentDisposition”, “attachment;filename=\”${downloadFileName}\”“})

修改之后执行取消,效果如下:
[WARN] StreamResultX Warn : socket write error
注1:我执行的时候并没有这个效果,什么提示都没有>_<
**注2**struts2-sunspoter-stream-1.1.jar 下载直接使用会报错:因为struts2-sunspoter-stream-1.1.jar 只是JDK1.4编译的,在1.6以上情况下报错。解决方法是反编译其原代码,只有1个类,然后重新导出1.6JAR,就可以解决了。

引用文献(深表感谢)

http://bear.conan.blog.163.com/blog/static/970124612013017113518929/

0 0