zoukankan      html  css  js  c++  java
  • Struts2下多文件的上传与下载

    转载自http://www.blogjava.net/lishunli/archive/2010/01/07/308614.html#_Toc246867260

    目录

    关键词

    写在前面

    需求

    环境

    目录结构

    重要文件的看点

    web.xml

    struts.xml

    UploadAction

    DownloadAction

    UploadConfigurationRead

    工程结果截图

    提供原代码下载

    关键词

    多文件 上传 下载 随意文件 java Struts2 单例 配置 动态读取 李顺利 

    写在前面

        在网络上,对于Java处理文件上传和下载的技术比较多,而Struts作为一款优秀的框架也提供了非常方便的文件上传和下载,而网上的一些例程都非常的不全面,概括来:

    1)   文件上传比较多,多文件上传少一点

    2)   文件下载很少的,看似简单,实则不然

    3)   文件下载一般都是单文件或者固定的文件,并没有(很少)实现随意文件的下载的例子

    最近也在研究一下文件的上传和下载,在整合网上、浪曦风中叶老师和自己的学习的思想,写了这个工程,提供给大家参考,所以的代码终在IE、FireFox、Chrome测试通过。

    需求

    1.能够对多个文件进行上传(可以选择上传文件个数,也即上传文件个数不定)

    2.能够对上传路径进行配置文件(upload.properties)指定,使用了一些类似单例模式的静态代码块

    3.对配置文件中的路径可以进行动态读取(不重启服务器)

    4.Struts2进行下载处理,能对上传的所有文件进行下载(多个)

    5.文件保存的名称UUID生成,不过显示并下载的名称都是原文件名称

    (人性化,通过UploadFiles处理)

     

    环境

    最新的Struts2:struts-2.1.8、MyEclipse、Tomcat、IE、FireFox、Chrome

     

    目录结构

     

     

    重要文件的看点

    web.xml

        <filter>

            <filter-name>struts2</filter-name>

            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

        </filter>

        在web.xml中使用了最新的Struts2的中央处理器类org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,而不再是以前的org.apache.struts2.dispatcher.FilterDispatcher,FilterDispatcher在新版本Struts2中已经标注为过时了,请大家尽量使用最新的filter。

     

    struts.xml

    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE struts PUBLIC

        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

        "http://struts.apache.org/dtds/struts-2.0.dtd">

    <struts>

        <constant name="struts.i18n.encoding" value="utf8" />

        <package name="file" namespace="/" extends="struts-default">

           <action name="showUpload">

               <result>/upload.jsp</result>

           </action>

           <action name="upload" class="org.usc.file.UploadAction">

               <result name="input">/upload.jsp</result>

    <!--          <result name="success">/upload_success.jsp</result>-->

               <result name="success">/download.jsp</result>

               <interceptor-ref name="fileUpload">

    <!--大家可以设置成自己的配置,想文件类型和大小等限制          -->

    <!--              <param name="maximumSize">2097152</param>单位是字节   2M  (2097152B)       -->

    <!--              <param name="allowedTypes">image/bmp,image/x-png,image/png,image/gif,image/jpeg,image/jpg,image/pjpeg</param>-->

    <!--              -->

    <!--                 容许文件类型为doc,ppt,xls,pdf,txt,java-->

    <!--              -->

               </interceptor-ref>

               <interceptor-ref name="defaultStack"></interceptor-ref>

           </action>

     

           <action name="download" class="org.usc.file.DownloadAction">

               <result name="success" type="stream">

                  <param name="contentDisposition">attachment;filename="${fileName}"</param>

                  <param name="inputName">downloadFile</param>

               </result>

           </action>

        </package>

    </struts>

     

    就是文件上传和下载的一些Struts2配置,注意上传的时候,请引入

    <interceptor-ref name="defaultStack"></interceptor-ref>,

    下载的配置中注意:<param name="inputName">downloadFile</param>

    其他的配置解释网上很多,不懂的可以先google学习一下。

     

    UploadAction

    在此文件中请注意文件数组的使用,因为是多文件

     

    package org.usc.file;

    import java.io.File;

    import java.util.ArrayList;

    import java.util.List;

    import java.util.UUID;

    import org.apache.commons.io.FileUtils;

    import org.apache.struts2.ServletActionContext;

    import org.usc.utils.UploadConfigurationRead;

    import com.opensymphony.xwork2.ActionSupport;

     

    /**

     * 多文件上传类

     *

     * @author MZ

     *

     * @Time 2009-11-24下午09:26:44

     */

    public class UploadAction extends ActionSupport

    {

     

        /**

         *

         */

        private static final long serialVersionUID = 1L;

        private File[] upload;// 实际上传文件

        private String[] uploadContentType; // 文件的内容类型

        private String[] uploadFileName; // 上传文件名

        private List<UploadFiles> uploadFiles = new ArrayList<UploadFiles>();

     

        public String execute() throws Exception

        {

           try

           {

               String targetDirectory = ServletActionContext.getServletContext()

                      .getRealPath("/"+ UploadConfigurationRead.getInstance().getConfigItem("uploadFilePath").trim());// 获得路径

               for (int i = 0; i < upload.length; i++)

               {

                  String fileName = uploadFileName[i];// 上传的文件名

                  String type = uploadContentType[i];// 文件类型

                  String realName = UUID.randomUUID().toString()+ getExt(fileName);// 保存的文件名称,使用UUID+后缀进行保存

     

                  File target = new File(targetDirectory, realName);

                  FileUtils.copyFile(upload[i], target);// 上传至服务器的目录,一般都这样操作,

                                                     // 在把路径写入数据库即可

     

                  UploadFiles uf = new UploadFiles();// 创建文件

                  uf.setUploadContentType(type);

                  uf.setUploadFileName(fileName);

                  uf.setUploadRealName(realName);

     

                  uploadFiles.add(uf);// 添加到需要下载文件的List集合中

     

              

               }

               ServletActionContext.getRequest().setAttribute("uploadFiles",

                      uploadFiles);

     

           } catch (Exception e)

           {

               e.printStackTrace();

               addActionError(e.getMessage());

     

               return INPUT;

           }

     

           return SUCCESS;

     

        }

     

        public File[] getUpload()

        {

           return upload;

        }

     

        public void setUpload(File[] upload)

        {

           this.upload = upload;

        }

     

        public String[] getUploadContentType()

        {

           return uploadContentType;

        }

     

        public void setUploadContentType(String[] uploadContentType)

        {

           this.uploadContentType = uploadContentType;

        }

     

        public String[] getUploadFileName()

        {

           return uploadFileName;

        }

     

        public void setUploadFileName(String[] uploadFileName)

        {

           this.uploadFileName = uploadFileName;

        }

     

        public static String getExt(String fileName)

        {

           return fileName.substring(fileName.lastIndexOf("."));

        }

     

    }

     

     

     

    DownloadAction

    在此文件中要注意public InputStream getDownloadFile()的名称在Struts2配置文件配置,返回的是一个InputStream类型的对象。

     

    package org.usc.file;

     

    import java.io.InputStream;

    import java.io.UnsupportedEncodingException;

    import com.opensymphony.xwork2.ActionSupport;

    import org.apache.struts2.ServletActionContext;

    import org.usc.utils.UploadConfigurationRead;

     

    public class DownloadAction extends ActionSupport

    {

        private static final long serialVersionUID = 6329383258366253255L;

        private String fileName;

        private String fileRealName;

        public void setFileName()

        {

           // 得到请求下载的文件名

           String fname = ServletActionContext.getRequest().getParameter("name");

           String frealname = ServletActionContext.getRequest().getParameter("realname");

           try

           {

               /*

                * 对fname参数进行UTF-8解码,注意:实际进行UTF-8解码时会使用本地编码,本机为GBK。

                * 这里使用request.setCharacterEncoding解码无效.

                * 只有解码了getDownloadFile()方法才能在下载目录下正确找到请求的文件

                */

               fname = new String(fname.getBytes("ISO-8859-1"), "UTF-8");

               frealname= new String(frealname.getBytes("ISO-8859-1"), "UTF-8");

           } catch (Exception e)

           {

               e.printStackTrace();

           }

           this.fileName = fname;

           this.fileRealName = frealname;

    //     System.out.println(fileName);

    //     System.out.println(fileRealName);

        }

     

        /*

         * @getFileName 此方法对应的是struts.xml文件中的: <param

         * name="contentDisposition">attachment;filename="${fileName}"</param>

         * 这个属性设置的是下载工具下载文件时显示的文件名, 要想正确的显示中文文件名,我们需要对fileName再次编码

         * 否则中文名文件将出现乱码,或无法下载的情况

         */

        public String getFileName() throws UnsupportedEncodingException

        {

     

           fileRealName = new String(fileRealName.getBytes(), "ISO-8859-1");

     

           return fileRealName;

        }

     

        /*

         * @getDownloadFile 此方法对应的是struts.xml文件中的: <param

         * name="inputName">downloadFile</param> 返回下载文件的流,可以参看struts2的源码

         */

        public InputStream getDownloadFile()

        {

     

           this.setFileName();

           returnServletActionContext.getServletContext().getResourceAsStream("/"+UploadConfigurationRead.getInstance().getConfigItem("uploadFilePath").trim()+"/" + fileName);

        }

     

        @Override

        public String execute() throws Exception

        {

           return SUCCESS;

        }

    }

    UploadConfigurationRead

    动态读取配置文件,借鉴网上的代码

     

    package org.usc.utils;

    import java.io.File;

    import java.io.FileInputStream;

    import java.net.URI;

    import java.net.URISyntaxException;

    import java.util.Properties;

    /**

     * 动态读取配置文件类

     *

     * @author MZ

     *

     * @Time 2009-11-24下午08:25:22

     */

    public class UploadConfigurationRead {

     

        /**

         * 属性文件全名,需要的时候请重新配置PFILE

         */

        private static String PFILE = "upload.properties";

     

        /**

         * 配置文件路径

         */

        private URI uri = null;

     

        /**

         * 属性文件所对应的属性对象变量

         */

        private long m_lastModifiedTime = 0;

     

        /**

         * 对应于属性文件的文件对象变量

         */

        private File m_file = null;

     

        /**

         * 属性文件所对应的属性对象变量

         */

        private Properties m_props = null;

     

        /**

         * 唯一实例

         */

        private static UploadConfigurationRead m_instance = new UploadConfigurationRead();

     

        /**

         * 私有构造函数

         *

         * @throws URISyntaxException

         */

        private UploadConfigurationRead() {

           try {

               m_lastModifiedTime = getFile().lastModified();

               if (m_lastModifiedTime == 0) {

                  System.err.println(PFILE + "file does not exist!");

               }

               m_props = new Properties();

               m_props.load(new FileInputStream(getFile()));

     

           } catch (URISyntaxException e) {

               System.err.println(PFILE+"文件路径不正确");

               e.printStackTrace();

           } catch (Exception e) {

               System.err.println(PFILE+"文件读取异常");

               e.printStackTrace();

           }

        }

     

        /**

         * 查找ClassPath路径获取文件

         *

         * @return File对象

         * @throws URISyntaxException

         */

     

        private File getFile() throws URISyntaxException {

           URI fileUri = this.getClass().getClassLoader().getResource(PFILE).toURI();

           m_file = new File(fileUri);

           return m_file;

        }

     

        /**

         * 静态工厂方法

         *

         * @return 返回ConfigurationRead的单一实例

         */

        public synchronized static UploadConfigurationRead getInstance() {

           return m_instance;

        }

     

        /**

         * 读取一特定的属性项

         */

        public String getConfigItem(String name, String defaultVal) {

           long newTime = m_file.lastModified();

           // 检查属性文件是否被修改

           if (newTime == 0) {

               // 属性文件不存在

               if (m_lastModifiedTime == 0) {

                  System.err.println(PFILE + " file does not exist!");

               } else {

                  System.err.println(PFILE + " file was deleted!!");

               }

               return defaultVal;

           } else if (newTime > m_lastModifiedTime) {

               m_props.clear();

               try {

                  m_props.load(new FileInputStream(getFile()));

               } catch (Exception e) {

                  System.err.println("文件重新读取异常");

                  e.printStackTrace();

               }

           }

           m_lastModifiedTime = newTime;

           String val = m_props.getProperty(name);

           if (val == null) {

               return defaultVal;

           } else {

               return val;

           }

        }

     

        /**

         * 读取一特定的属性项

         *

         * @param name

         *            属性项的项名

         * @return 属性项的值(如此项存在), 空(如此项不存在)

         */

        public String getConfigItem(String name) {

           return getConfigItem(name, "");

        }

     

    }

     

     

    工程结果截图

    在IE(遨游)中多文件上传

     

    在IE(遨游)中多文件下载

     

    在Firefox中多文件上传

     

    在Firefox中多文件下载

     

    在Chrome中多文件上传

     

    在Chrome中多文件下载

     

    服务器中所以文件

     

    提供原代码下载

    FileUpLoadAndDownLoad 
    multi-files-upload-and-download(maven)

    为了有更好得兼容性,这个小demo已经移植到用maven构建(有些网页反映在eclipse里面部署失败),你可以下载上面的标记为maven的源码,或者通过

    svn checkout 
    http://usc.googlecode.com/svn/trunk/multi-files-upload-and-download/  
    or

    git clone git://github.com/lishunli/multi-files-upload-and-download.git
    or
    fork https://github.com/lishunli/multi-files-upload-and-download

    后,自己进行maven install并部署
     

    如果你已经看到这儿了,那就请再欣赏 使用Struts2上传图片存取到Mysql中并读取出来显示在页面上 另一篇有点类似的博客吧,谢谢。

    实际上,这个还可以进行扩展,可以存取上传的文件名和路径到数据库中,再在UI(jsp)上面根据需求进行显示文件,并提供下载,仅抛下砖头了,其它的...如果有什么建议或意见可以通过Q:506817493  Eleeshunli<at>qq.com,大家一起交流。

     

  • 相关阅读:
    找水王
    环状二维数组最大子数组和
    用户模板
    课堂作业-电梯调度
    书店折扣问题
    《软件工程》读后感
    首尾相连的二维数组最大子数组求和
    梦断代码读后感(二)
    返回一个整数数组中最大子数组的和之测试
    首尾相连的一位数组最大子数组和
  • 原文地址:https://www.cnblogs.com/luyesql/p/3135494.html
Copyright © 2011-2022 走看看