zoukankan      html  css  js  c++  java
  • 文件下载

    一、原理

    1.单文件下载
    (1)找出文件在Web应用的虚拟路径。 如 "WEB-INF/data/1.jpg"。
    (2)根据虚拟路径,查找出该文件在服务器硬盘中的物理地址。
    (3)读入输入流。
    (4)设置响应类型,为固定格式:
    resp.setContentType("applicaton/x-msdownload");
    (*5)需要对文件名进行编码,因为中文下会出现乱码:
    fileName = URLEncoder.encode(fileName, "UTF-8");
    (6)设置响应头Content-Disposition:
    resp.setHeader("Content-Disposition", "attachment;filename="+fileName);
    (7)以响应输出流的方式返回响应。
    (8)关闭两个流。

    示例代码:

    String filePath = "/WEB-INF/data/" + fileName;
    String realPath = getServletContext().getRealPath(filePath);
    InputStream is = new FileInputStream(realPath);
    resp.setContentType("applicaton/x-msdownload");
    fileName = URLEncoder.encode(fileName, "UTF-8");
    resp.setHeader("Content-Disposition", "attachment;filename="+fileName);
    
    ServletOutputStream os = resp.getOutputStream();
    byte[] b = new byte[1024];
    int len = 0;
    
    while((len = is.read(b)) != -1) {
    os.write(b, 0, len);
    }
    is.close();
    os.close();

    说明:
    通过 a 标签的 href 指向资源位置,也可以提供下载,但是存在一个问题,若下载的文件是浏览器本身可以解析的话,浏览器会打开,而不会下载。

    2.多文件打包下载:
    与单文件下载的区别:
    (1)设置响应类型:
    resp.setContentType("Content-type: text/zip");
    (2)设置响应头:
    resp.setHeader("Content-Disposition", "attachment; filename=mytest.zip");
    (3)使用 ZipOutputStream 对 ServletOutputStream 进行包装。
    (4)遍历每一个要下载的文件,为每个文件创建对应的Entry然后放入 ZipOutputStream 中。
    (5)读取该文件,然后以 ZipOutputStream 的形式写出。

    示例代码:

    String filePathBase = "/WEB-INF/data/";
    String filePath = filePathBase + "1.jpg";
    String filePath2 = filePathBase + "项目中出现的问题.txt";
    
    List<File> files = new ArrayList<>();
    files.add(new File(req.getSession().getServletContext().getRealPath(filePath)));
    files.add(new File(req.getSession().getServletContext().getRealPath(filePath2)));
    
    resp.setContentType("Content-type: text/zip");
    resp.setHeader("Content-Disposition", "attachment; filename=mytest.zip");
    
    ServletOutputStream os = resp.getOutputStream();
    ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(os));
    for(File file : files) {
    zos.putNextEntry(new ZipEntry(file.getName()));
    
    InputStream fis = new FileInputStream(file);
    
    BufferedInputStream bis = new BufferedInputStream(fis);
    
    int data = 0;
    while((data = fis.read()) != -1) {
    zos.write(data);
    }
    
    bis.close();
    zos.closeEntry();
    
    }
    zos.close();

    二、Struts2

    1.参考 Struts2 docs 中 Result Types → Stream Result。

    <result name="success" type="stream">
      <param name="contentType">image/jpeg</param>
      <param name="inputName">inputStream</param>
      <param name="contentDisposition">attachment;filename="document.pdf"</param>
      <param name="bufferSize">1024</param>
    </result>

    2.以上属性可以在 Action 中以 getXxx() 方法提供。

    3.需要注意下载文件若为中文,需要对其进行 "UTF-8" 编码

    4.例子:

    <s:a value="/downLoad">点我</s:a>
    form
    <action name="downLoad" class="com.nucsoft.download.DownLoadAction">
                <result name="success" type="stream">
                    <param name="contentType">text/xml</param>
                    <param name="inputName">inputStream</param>
                    <!--<param name="contentDisposition">attachment;filename="你好.xml"</param>-->
                </result>
    </action>
    struts.xml
    /**
     * @author solverpeng
     * @create 2016-07-12-20:04
     */
    public class DownLoadAction extends ActionSupport{
        private InputStream inputStream;
    
        public InputStream getInputStream() {
            return inputStream;
        }
    
        public String contentDisposition;
    
        public String getContentDisposition() throws UnsupportedEncodingException {
            String fileName = URLEncoder.encode("你好.xml", "UTF-8");
            String contentDisposition = "attachment;filename=""+fileName+""";
            return contentDisposition;
        }
    
        @Override
        public String execute() throws Exception {
            String realPath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/你好.xml");
            inputStream = new FileInputStream(realPath);
            return SUCCESS;
        }
    }
    DownLoadAction

    未完,待续。

  • 相关阅读:
    在Android studio中使用“.jpg”图片
    杨辉三角形简便代码
    Java中对象的理解
    对数据库的简单操作
    通过分析周榜前100名专家的博客文章 手把手教你写出爆款文章
    【Spring】4.助你跟面试官侃一个小时的IOC
    【Spring】3.助你跟面试官侃一个小时的AOP
    【Spring】2.如何给面试官讲SpringBean的声明周期
    【Spring】1. Spring概要综述
    【Java并发编程】8.面试不扯点JMM怎么显得专业呢
  • 原文地址:https://www.cnblogs.com/solverpeng/p/5613738.html
Copyright © 2011-2022 走看看