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

    文件下载的核心思想即是将文件从一个地方拷贝到另一个地方.

    1.传统方式:

      在Action中加入大量servlet api 操作.优点是好理解,缺点是耦合度高。

    2.stream方式:

         使用struts2中的stream拦截器进行操作

    二.实例:

    我这里用的是maven,贴出pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.amos</groupId>
        <artifactId>struts2_learn</artifactId>
        <packaging>war</packaging>
        <version>0.0.1-SNAPSHOT</version>
        <name>struts2_learn Maven Webapp</name>
        <url>http://maven.apache.org</url>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.struts</groupId>
                <artifactId>struts2-core</artifactId>
                <version>2.3.16</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-io</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>1.1.2</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>
        </dependencies>
        <build>
            <finalName>struts2_learn</finalName>
        </build>
    </project>
    

      

    1.使用传统方式实现文件下载:

    DownloadAction.java

    package download;
    
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.struts2.ServletActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    /** 
    * @ClassName: DownloadAction 
    * @Description: 文件下载
    * @author: amosli
    * @email:amosli@infomorrow.com
    * @date Feb 13, 2014 1:22:23 AM  
    */
    public class DownloadAction extends ActionSupport {
        private static final long serialVersionUID = -5609061774548242181L;
        private String fileName;//文件名称
        public void setFileName(String fileName) {
            if (ServletActionContext.getRequest().getMethod().equals("GET")) {
                try {
                    byte[] bytes = fileName.getBytes("ISO8859-1");//将get方式提交的中文进行处理,即将编码由ISO8859-1转为utf-8
                    fileName = new String(bytes, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
            this.fileName = fileName;
        }
    
        // 下载
        public String execute() throws Exception {
            // 1.传统下载方式
            // 取得HttpServletResponse对象
            HttpServletResponse response = ServletActionContext.getResponse();
            // 取得ServletContext对象
            ServletContext context = ServletActionContext.getServletContext();
            // 通知浏览器以下载方式打开文件
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
            // 取得需要下载文件的根目录
            String realPath = context.getRealPath("/WEB-INF/download");
            // 构造子节输入流
            InputStream is = new FileInputStream(realPath + "/" + fileName);
            // 构造子节输出流
            OutputStream os = response.getOutputStream();
            byte[] b = new byte[1024];
            int len = 0;
            while ((len = is.read(b)) > 0) {
                os.write(b, 0, len);
            }
            is.close();
            os.close();
            return null;
        }
    }
    

      download.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix="c" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        英文需要编码
        <a href="/struts2_learn/DownloadAction?fileName=building.jpg"
            style="text-decoration: none">
            building.jpg 
        </a> <hr>
        <%-- <c:url var="myURL" value="/DownloadAction">
            <c:param name="fileName" value="建筑.jpg" />
        </c:url>
        <a href="${myURL}" style="text-decoration: none"> 建筑.jpg </a> --%>
    </body>
    </html>
    

      download_struts.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    <struts>
            <package name="download" extends="struts-default">
                <action name="DownloadAction" class="download.DownloadAction" method="execute">
                </action>
            </package>
    </struts>
    

      struts.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
        <!--<include file="config/upload.xml"></include> -->
        <!-- 加载其他配置文件 -->
        <!-- <include file="config/upload-interceptor.xml"></include> -->
        <!-- 加载属性文件-国际化 -->
        <!-- <constant name="struts.custom.i18n.resources" value="message"></constant> -->    <!-- 结果集 -->
        <!-- <include file="config/result_struts.xml"></include> -->
        <!-- 类型转换 -->
        <!-- <include file="config/type_struts.xml"></include> -->
        <!-- 文件下载 -->
        <include file="config/download_struts.xml"></include>
    </struts>
    

      效果如下图所示,点击building.jpg即可开始下载:

         

    代码运行顺序:

    首先,项目启动,加载struts.xml--->download_struts.xml-->将对应的DownloadAction加载.

    其次,用户访问download.jsp页面,点击超链接,即开始调用DownloadAction进行下载.

    核心程序即为DownloadAction.java,将要下载的文件写入到输入流,FileInputStream,然后再将文件从输入流写入到输出流,即将文件从一个地方拷贝到另一个地方.HttpServletResponse,将文件回写给浏览器,以达到下载文件的目的.

    最后,文件成功下载,文件被拷贝到指定的地方.

    这里要注意的是如果是GET请求方式,那么要注意中文乱码的问题,这里涉及到转码的问题,要做一个判断,详情可参考上面的代码.

    2.使用stream方式进行文件下载:

    DownloadStreamAction.java

    package download;
    import java.io.InputStream;
    import java.net.URLEncoder;
    import org.apache.struts2.ServletActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    /** 
    * @ClassName: DownloadStreamAction 
    * @Description: 现代下载方式
    * @author: amosli
    * @email:amosli@infomorrow.com
    * @date Feb 13, 2014 12:35:26 AM  
    */
    public class DownloadStreamAction extends ActionSupport {
        private static final long serialVersionUID = -2747191035343710583L;
        private String fileName;
        public void setFileName(String fileName) throws Exception {
            if(ServletActionContext.getRequest().getMethod().equals("GET")){
                byte[] bytes = fileName.getBytes("ISO8859-1");
                fileName=new String(bytes,"utf-8");
            }
            this.fileName = fileName;
        }
        public String getFileName() throws Exception {
            return URLEncoder.encode(fileName, "utf-8");
        }
        public InputStream getImageStream() throws Exception {
            InputStream inputStream = ServletActionContext.getServletContext().getResourceAsStream("/WEB-INF/download/"+fileName);
            return inputStream;
        }
    }
    

      download_struts.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    <struts>
            <!-- <package name="download" extends="struts-default">
                <action name="DownloadAction" class="download.DownloadAction" method="execute">
                </action>
            </package> -->
            <package name="download" extends="struts-default">
                <action name="DownloadAction" class="download.DownloadStreamAction" method="execute">
                <!-- 以stream二进制流的方式打开 -->
                <result name="success" type="stream">
                    <!-- 指明文件的下载类型 -->
                    <param name="contentType">image/jpeg</param>    
                    <!-- 指明如果取得需要下载文件的InputStream输入流 -->
                    <param name="inputName">imageStream</param>    
                    <!-- 指明让浏览器以下载框的方式打开 -->
                    <param name="contentDisposition">attachment;filename="building.jpg"</param>    
                    <!--<param name="contentDisposition">attachment;filename=${fileName}</param>-->    
                    <!-- 指明下载文件时的字符数组byte[]大小 -->
                    <param name="bufferSize">1024</param>
                </result>
                </action>
            </package>
    </struts>
    

      

    这里如果仅仅看DownloadStreamAction,会发现代码简洁明了,少了很多,再看download_struts.xml,会发现之前我们自己做的事,都被struts代替了,比如字符数组的大小,这里以参数配置的形式出现,方便了许多.

    注意:imageStream要和DownloadStreamAction中的getImageStream相对应,不可写错.

    关于其具体实现可以查看org.apache.struts2.dispatcher.StreamResult源码,其对应参数,看过源码后就会发现其实下载和传统方式差不多,就是将其优化了不少.

  • 相关阅读:
    spring源码阅读(一)
    多线程学习(十)
    多线程学习(九)
    多线程学习(八)
    多线程学习(七)
    多线程学习(六)
    多线程学习(五)
    多线程学习(四)
    matlab-table
    Matlab
  • 原文地址:https://www.cnblogs.com/tony-hyn/p/7651371.html
Copyright © 2011-2022 走看看