• Struts2文件上传下载(二)


    如果用户下载的文件是中文名,或者是在下载前检查用户的权限,就要使用Struts2提供的文件下载。在前台页面上提供一个链接,这个链接指向一个存在于服务器上的文件,并且文件的名字是中文名称,对中文名称进行URL编码。以下是download.jsp文件的内容:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@page import="java.net.URLEncoder"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>文件下载</title>
      </head>
      <body>
        <a href="struts2download.action?fileName=<%=URLEncoder.encode("download中文.doc","UTF-8") %>">下载</a>
      </body>
    </html>
    Action类:

    package com.jason.web.action;
    
    import java.io.InputStream;
    import org.apache.struts2.ServletActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    
    public class DownLoadAction extends ActionSupport{
    	private static final long serialVersionUID = -6103161491484708345L;
    	
    	private String fileName; // 要下载的文件的名称
    	private String downDir;// 下载文件夹由struts在配置文件中注入
    	private String fileEncoding;// 文件名 字符集
    	
    //	省略Getter、Setter方法
    
    	public InputStream getDownloadStream() throws Exception {
    		// 对于get方式提交的数据需要我们手工进行转码
    		fileName = new String(fileName.getBytes("iso-8859-1"), fileEncoding);
    		// 取得文件的路径
    		String filePath = downDir + "/" + fileName;
    //		System.out.println(filePath);
    		return ServletActionContext.getServletContext().getResourceAsStream(filePath);
    	}
    	
    	@Override
    	public String execute() throws Exception {
    		return SUCCESS;
    	}
    }

    struts.xml配置文件

    <action name="struts2download" class="com.jason.web.action.DownLoadAction">
    			<param name="downDir">/download</param>
    			<param name="fileEncoding">UTF-8</param>
    			<result type="stream">
    				<param name="inputName">downloadStream</param>
    				<!--下载文件的缓冲区大小-->
    				<param name="bufferSize">4096</param>
    				<!--
    					如果想让用户直接使用浏览器打开,我们可以直接指定正确的类型。
    					如果不好确定类型,可以使用application/octet-stream,表示二进制流
    				-->
    				<param name="contentType">application/octet-stream;charset=iso-8859-1</param>
    				<param name="contentDisposition">attachment;filename="${fileName}"</param>
    			</result>
    		</action>

    运行OK!但是当取消下载时会报错
    java.lang.IllegalStateException
    异常原因分析:  stream对应的类是org.apache.struts2.dispatcher.StreamResult,该类的处理过程如下:1。配置其中result标签下的各个参数2。从服务器中获取输入流,并同时与客户端建立输出流(服务器与客户端链接通过Socket进行连接)3。当点击“保存”或“打开”时,开始传输数据。如果点击“取消”,关闭所有的流。  这里要注意的是,但是实际发现Socket并没有断开!并且流也没有关闭!这一点非常重要!  所以在JSP容器通过Response获取输出流之前,前面的流并没有关闭,所以会造成该异常的报出。
    解决办法:
    需要下载struts2-sunspoter-stream-1.0.jar,并复制在/WEB-INF/lib下
    struts.xml配置修改如下:
                    
    <result-types>  
    		     <result-type name="streamx" class="com.sunspoter.lib.web.struts2.dispatcher.StreamResultX"/>  
    		</result-types>
    		<action name="struts2download" class="com.jason.web.action.DownLoadAction">
    			<param name="downDir">/download</param>
    			<param name="fileEncoding">UTF-8</param>
    			<result type="streamx">
    				<param name="inputName">downloadStream</param>
    				<!--下载文件的缓冲区大小-->
    				<param name="bufferSize">4096</param>
    				<!--
    					如果想让用户直接使用浏览器打开,我们可以直接指定正确的类型。
    					如果不好确定类型,可以使用application/octet-stream,表示二进制流
    				-->
    				<param name="contentType">application/octet-stream;charset=iso-8859-1</param>
    				<param name="contentDisposition">attachment;filename="${fileName}"</param>
    			</result>
    		</action>
    只需添加一个result-type,将原有的result中type改为“streamx”,其他一律不变,在这种情况下,点击“取消”的同时也关闭了流,不会再报出该异常。
    再点击取消会出现警告
    WARN StreamResult:45 - StreamResultX Warn : socket write error 
    如果出现该警告说明正确执行,该警告说明,Socket非正常中断,但是流确实已经关闭,自此再也不用看到上面出现的讨厌异常结果。
  • 相关阅读:
    PLAYBOOK 命令统计资源利用率 输出本地文件 flask展示
    如何对PFX证书转换成PEM格式证书
    Openshift学习
    Playbook handlers使用
    网络空间安全基础篇(2)----wireshark
    网络空间安全基础篇(1)----nmap的使用
    opencv——图像掩码操作
    opencv图像阈值操作
    在图片上绘制图形和添加文字
    使用opencv去操作树莓派摄像头保存图片和视频
  • 原文地址:https://www.cnblogs.com/jasontec/p/9601736.html
Copyright © 2020-2023  润新知