zoukankan      html  css  js  c++  java
  • strtus2.0实现下载

    (1)

    先来看下 Servlet 如何实现文件下载的,直接见代码:

    PrintWriter out = response.getWriter();
    //不管实际类型,待下载文件 ContentType 统一指定为 application/octet-stream
    response.setContentType("application/octet-stream");
    //中文文件名必须转码为 ISO8859-1,否则为乱码
    String fileName = new String("文本文件.txt".getBytes(), "ISO8859-1");
    //作为附件下载,相应的 "inline;filename = "+fileName 是在线(浏览器中显示内容)打开
    response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
    //因为文件编码也为 ISO8859-1,所以内容须转码成 ISO8859-1,尚不知如何控制下载文本文件的编码
    //或有谁知道的,还请告诉我一下。 文件内容可以从物理文件中来,或者数据库中读取填入等等
    out.write(new String("Servlet 文件下载测试".getBytes(), "ISO8859-1"));
    out.close();

    知道了上面各行的含义,再来看下 Struts2 的解决方式,其实不过是把某些代码的功能移入到了配置文件而已。在李刚所著的《Struts 2 权威指南》中说 Struts 实现文件下载是由一个 download 拦截器。其实不然,只是一个 StreamResult(org.apache.struts2.dispatcher.StreamResult) 而已,也不像实现文件上传那样要额外的 JAR 包。

    在 StreamResult 中有以下几个默认属性要留意一下:
        public static final String DEFAULT_PARAM = "inputName";

        protected String contentType = "text/plain";
        protected String contentDisposition = "inline";
        protected String inputName = "inputStream";
        protected InputStream inputStream;
        protected int bufferSize = 1024;
    StreamResult 的实现细节敬请阅读它的源代码,实现过程一言以蔽之就是:从 inputStream 获取内容,以相应的 contentType、contentDisposition 和 bufferSize 输出给浏览器,对 contentType 和 contentDisposition 的相应设置就能实现文件下载,可对照前面 Servlet 的实现。看个实际的例子吧。

    struts.xml 中 Action 的配置,假定 Action 类为 com.unmi.DownLoadAction

    <action name="download" class="com.unmi.action.DownloadAction">
      <result name="success" type="stream"><!--type 为 stream 应用 StreamResult 处理-->
             <param name="contentType">application/octet-stream</param><!--默认为 text/plain-->
             <!-- 默认就是 inputStream,它将会指示 StreamResult 通过 inputName 属性值的 getter 方法,比如这里就是 getInputStream() 来获取下载文件的内容,意味着你的 Action 要有这个方法 -->
             <param name="inputName">inputStream</param>
             <!-- 默认为 inline(在线打开),设置为 attachment 将会告诉浏览器下载该文件,filename 指定下载文件保有存时的文件名,若未指定将会是以浏览的页面名作为文件名,如以 download.action 作为文件名,这里使用的是动态文件名,${fileName}, 它将通过 Action 的 getFileName() 获得文件名 -->
             <param name="contentDisposition">attachment;filename="${fileName}"</param>
             <param name="bufferSize">4096</param><!-- 输出时缓冲区的大小 -->
      </result>

    说明:对于上面的配置其他参数可以用默认值,关键就是 contentDisposition 要设置为 attachment 才能提示下载,同时用 filename 指定文件名,若直接指定非动态的文件名。

    DownloadAction 代码,需要实现 getInputStream() 返回输入流;因前面用的动态文件名,所以须加上 getFileName() 返回文件名,若非动态文件名,则该方法可省去。

    package com.unmi.action;
    import java.io.*;
    import java.text.*;
    import java.util.Date;
    /**
    * 文件下载的 Action    
    * @author Unmi
    */
    public class NetbookSerialAction {
    public String execute() throws Exception {
    //这里可加入权限控制
    return "success";
      }
    //获得下载文件的内容,可以直接读入一个物理文件或从数据库中获取内容
    public InputStream getInputStream() throws Exception {
    //return new FileInputStream("somefile.rar"); 直接下载 somefile.rar
    //和 Servlet 中不一样,这里我们不需对输出的中文转码为 ISO8859-1
    return new ByteArrayInputStream("Struts2 文件下载测试".getBytes());
      }
    //对于配置中的 ${fileName}, 获得下载保存时的文件名
    public String getFileName() {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String fileName = "序列号(" + df.format(new Date()) + ").txt";
    try {
    //中文文件名也是需要转码为 ISO8859-1,否则乱码
    return new String(fileName.getBytes(), "ISO8859-1");
        } catch (UnsupportedEncodingException e) {
    return "impossible.txt";
        }
      }
    }

    谨记一个就是,要想下载的文件名不乱码就要以 ISO8859-1 字符集进行转码,内容会否乱码可在调试中解决。
    好啦,启动服务,访问 http://localhost:8080/teststruts2/download.action,浏览器便会提示下载 序列号(2009-06-17).txt,内容为:“Struts2 文件下载测试”。

  • 相关阅读:
    数据类型装换
    变量及数据类型
    27 网络通信协议 udp tcp
    26 socket简单操作
    26 socket简单操作
    14 内置函数 递归 二分法查找
    15 装饰器 开闭原则 代参装饰器 多个装饰器同一函数应用
    12 生成器和生成器函数以及各种推导式
    13 内置函数 匿名函数 eval,exec,compile
    10 函数进阶 动态传参 作用域和名称空间 函数的嵌套 全局变量
  • 原文地址:https://www.cnblogs.com/hyteddy/p/2113166.html
Copyright © 2011-2022 走看看