public class TestAction extends ActionSupport{
   
    public String fileLoad() throws IOException{
        String fileName = ServletActionContext.getRequest().getParameter("fileName");
        //要处理中文乱码问题
        fileName = new String(fileName.getBytes("iso8859-1"),"utf-8");
        //要下载的哪个文件
        String path = ServletActionContext.getServletContext().getRealPath("/");//得到项目的根目录
        InputStream is = new FileInputStream(path+"/download/"+fileName);
       
        //下载到哪里?客户端
        HttpServletResponse response = ServletActionContext.getResponse();
        OutputStream os = response.getOutputStream();
        //弹出下载的框filename:提示用户下载的文件名
        response.addHeader("content-disposition", "attachment;filename="+java.net.URLEncoder.encode(fileName,"utf-8"));
       
        byte[] b = new byte[1024];
        int size = is.read(b);
        while(size>0){
            os.write(b,0,size);
            size = is.read(b);
        }
        is.close();
        os.close();
        return null;
    }
   
}

文件下载分为两步:读文件、写文件。从服务器读取,然后写到客户端去,所以需要InputStream和OutputStream。然后设置content-disposition弹出下载提示框,提示用户下载的文件名和从何处下载的。下面一段代码是读写文件的金典代码,我也不多讲了!

byte[] b = new byte[1024];
        int size = is.read(b);
        while(size>0){
            os.write(b,0,size);
            size = is.read(b);
        }

<struts>
   <package name="com.action" extends="struts-default">
           <action name="download" class="com.action.FileLoadAction">
               <result name="success" type="stream">
                   <param name="contentType">application/txt;</param>
                   <param name="inputName">downloadFile</param>
                   <param name="bufferSize">2048</param>
               </result>
           </action>
   </package>
</struts>

public class FileLoadAction extends ActionSupport{
    private String fileName;

public String getFileName() {
        return fileName;
    }
    public void setFileName(String fileName) throws UnsupportedEncodingException {
        this.fileName = new String(fileName.getBytes("iso8859-1"),"utf-8");
    }
    public InputStream getDownloadFile() throws UnsupportedEncodingException, FileNotFoundException{
        //attachment为进行文件保存,这个时候还可以附件另一个参数filename表示保存时的缺省名称
        //inline为在线打开,不进行保存
        ServletActionContext.getResponse().setHeader("Content-Disposition","attachment;fileName="+ java.net.URLEncoder.encode(fileName, "UTF-8"));
        HttpServletResponse response = ServletActionContext.getResponse();
        return new FileInputStream("d:/"+this.getFileName());
    }
    public String downloadFile(){
        return SUCCESS;
    }
}

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>

<s:url value="download.action" var="url">
    <s:param name="fileName">中文.txt</s:param>
</s:url>
<a href="${url }">点击下载</a>

action特殊的地方在于result的类型是一个流(stream),配置stream类型的结果时,因为无需指定实际的显示的物理资源,所以无需指定location属性,只需要指定inputName属性,该属性指向被下载文件的来源,对应着Action类中的某个属性,类型为InputStream,,struts2会寻找一个返回类型为InputStream的方法getInputStream()(方法名最好为getInputStream,有人说此方法名可以为别的可能需要与struts.xml中的inputName保存一致下面有解释,另一种理解:action中定义一个返回InputStream的方法,该方法作为被下载文件的入口,且需要配置stream类型结果时指定inputName参数,inputName参数的值就是方法去掉get前缀、首字母小写的字符串。

下面则列出了和下载有关的一些参数列表:

参数说明 
contentType 
内容类型,和互联网MIME标准中的规定类型一致,例如text/plain代表纯文本,text/xml表示XML,image/gif代表GIF图片,image/jpeg代表JPG图片 
 
inputName 
下载文件的来源流,对应着action类中某个类型为Inputstream的属性名,例如取值为inputStream的属性需要编写getInputStream()方法 
 
contentDisposition 
文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式,而附件方式会弹出文件保存对话框,否则浏览器会尝试直接显示文件。取值为: 
 
attachment;filename="struts2.txt",表示文件下载的时候保存的名字应为struts2.txt。如果直接写filename="struts2.txt",那么默认情况是代表inline,浏览器会尝试自动打开它,等价于这样的写法:inline; filename="struts2.txt" 
 
bufferSize 
下载缓冲区的大小

struts2download的更多相关文章

随机推荐

  1. java 导出word 并下载

    记录一下导出操作 源码: /************ * 导出word 并下载 * @param id 房号记录编号 * ***********************/ @RequestMappin ...

  2. odoo种种

    [精]Odoo 8.0深入浅出开发教程-模块开发基础 http://blog.csdn.net/sunansheng/article/details/50864527 搭建odoo开发调试环境 htt ...

  3. Matlab中^2和.^2的区别

    矩阵a a^2 --  两个矩阵相乘 a.^2  --  表示 矩阵对应位置相乘 如下: a=[ 1,2,3 4,5,6 7,8,9]; disp(a); disp(a^2); disp(a.^2); ...

  4. Apache报错信息之Invalid command 'Order', perhaps misspelled or defined by a module not included in the server config

    今天配置开启Apache虚拟主机时, 然后日志报错提示: Invalid command 'Order', perhaps misspelled or defined by a module not ...

  5. C++中重定义的问题——问题的实质是声明和定义的关系以及分离式编译的原理

    这里的问题实质是我们在头文件中直接定义全局变量或者函数,却分别在主函数和对应的cpp文件中包含了两次,于是在编译的时候这个变量或者函数被定义了两次,问题就出现了,因此,我们应该形成一种编码风格,即: ...

  6. git 远程仓库

    1.查看当前的远程库 git remote git remote -v 2.添加远程仓库 git remote add [shortname] [url] 3.从远程仓库抓取数据 git fetch ...

  7. Slave I/O: Got fatal error 1236

    [起因] 一次zabbix报警,从库[Warning] MySQL-repl was down  # 不知道主库/storage空间小于20%时为什么没有触发trigger [从库错误日志] 1611 ...

  8. ElasticSearch中bulkProcesser使用

    初次接触es,可能对增删改查很熟悉,以为能为得心应手,本次应用场景为 数据库变更一条记录,会触发更新es中的数据,每秒并发大概30条左右,测试环境一切工作正常(数据量较少),上线后发现日志中很多类似于 ...

  9. 【Phylab2.0】Beta版本项目展示

    团队成员 冯炜韬(PM)http://www.cnblogs.com/toka 岳桐宇(后端)http://www.cnblogs.com/mycraftmw 杨子琛(测试&LaTeX)htt ...

  10. 使用django开发博客过程记录4——Category分类视图

    在写点击博客的所属分类,显示所有该分类的文章时真是让我想了好一会,为什么呢?因为我使用的是cbv模式开发的而不是简单的视图处理逻辑的,所以,有些操作会被包装好了,你并不知道它的细节,那么我们今天要实现 ...