• Struts2的上传与下载


    转自:http://blog.csdn.net/Mark_LQ/article/details/49822821

    10.1.1 文件上传基本案例

      第一步:上传组件依赖与commons-fileupload-1.3.1.jar和commons-io-2.2.jar。这两个文件可以从http://commons.apache.org/下载或struts解压缩包中获取。
      第二步:把form表单的enctype设置为:“multipart/form-data“,如下:

    <form action="/Struts2Study/uploadFile.action" enctype="multipart/form-data" method="post">
        文件:<input name="uploadFile" type="file"><br>
        <input type="submit" value="上传文件">
    </form>

      enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。
      默认地,表单数据会编码为 application/x-www-form-urlencoded。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值)。

    属性值值描述
    application/x-www-form-urlencoded 在发送前编码所有字符(默认)
    multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
    text/plain 空格转换为 “+” 加号,但不对特殊字符编码。


      第三步:Action类中添加以下属性,表单中文件字段的名称name=”uploadFile”:

    private File uploadFile;  // 对应form表单中上传输入框的name值
    private String uploadFileContentType; // 上传文件类型ContentType固定写法
    private String uploadFileFileName; // 上传文件名FileName固定写法
    
    public String uploadFile() throws IOException {
        /*
         * struts2框架已经将上传的文件临时保存在uploadFile变量中,当action结束调用后,
         * 临时保存的文件就会删除,所以需要借助文件工具类保存到磁盘上!
         */
        /*
         * 获取上下文(项目)下files目录的绝对路径。
         * 考虑到:application.getRealPath(path)可以获取绝对路径
         * 所以application -> ServletActionContext.getServletContext()
         */
        String pathname = ServletActionContext.getServletContext().getRealPath("/files");
        // 如果保存的路径不存在,则创建
        File destDir = new File(pathname);
        if (!destDir.exists()) {
            destDir.mkdir();
        }
        //  destDir表示parentDir
        FileUtils.copyFile(uploadFile, new File(destDir, uploadFileFileName));
        return "message";
    }

      第四步:配置struts.multipart.saveDir常量
      Struts2中的struts.multipart.saveDir常量主要是用来设置上传文件的临时存放地址,而这个参数设置方法的不同对应的地址也不同。 如果访问量不是太大,空间足够,可以直接使用默认的临时地址。

    1.如果没有设置struts.multipart.saveDir,那么将默认使用javax.servlet.context.tempdir指定的地址,javax.servlet.context.tempdir的值是由服务器来确定的,临时文件的名称类似于upload__1a156008_1373a8615dd__8000_00000001.tmp。
    2.直接使用绝对地址(Linux为例)

     <constant name="struts.multipart.saveDir" value="/var/upload_temp_files"/>

      第五步:设置可上传文件的大小限制
      默认上传文件的最大值为 2097152字节,2M,如果上传的文件超过,则会报错。修改最大上传文件的大小:

    <constant name="struts.multipart.maxSize" value=“10701096"/>

    10.1.2 拦截器实现上传文件的过滤

      Struts2提供类一个文件上传的拦截器fileUpload,通过配置该拦截器可以实现上传文件的过滤。打开该拦截器所对应的类FileUploadInterceptor:

    public class FileUploadInterceptor extends AbstractInterceptor {
        protected Long maximumSize;
        protected Set<String> allowedTypesSet = Collections.emptySet();
        protected Set<String> allowedExtensionsSet = Collections.emptySet();
        ...
    }

      可知配置fileUpload拦截器有3个参数:

    - maximumSize:允许上传文件的大小限制,字节为单位
    - allowedTypes:允许上传的文件类型,多个文件类型采用,分隔
    - allowedExtensions:允许上传文件的后缀名

      当文件过滤失败后,添加错误信息到系统fildError域,转入到input视图,因此该action需要提供input视图。为了保证拦截器可以添加错误信息,action需要实现ValidationAware接口,可以直接基础ActionSupport类。
      (1)拦截器的配置如下:

    <action name="uploadFile" class="com.markliu.day04.UploadFileAction" method="uploadFile">
                <interceptor-ref name="fileUpload">
                        <param name="maximumSize">1024</param>
                        <param name="allowedTypes">image/bmp,image/jpg,image/png</param>
                        <param name="allowedExtensions">.bmp,.jpg,.png</param>
                </interceptor-ref>
                <interceptor-ref name="defaultStack" />
                <result name="message">/pages/day04/message.jsp</result>
                <result name="input">/pages/day04/uploadfile.jsp</result>
    </action>

      注意fileUpload拦截器必须在defaultStack(默认)拦截器前面配置,Struts2会由上到下执行拦截器。
      (2)由于defaultStack拦截器栈中已经包含fileUpload拦截器,所以配置简化如下:

    <interceptor-ref name="defaultStack">
            <param name="fileUpload.maximumSize">1024</param>
            <param name="fileUpload.allowedTypes">image/bmp,image/jpg,image/png</param>
            <param name="fileUpload.allowedExtensions">.bmp,.jpg,.png</param>                       
    </interceptor-ref>

      (3)修改显示国际化的错误信息:
      在上传文件处理的action所在包下创建资源文件:一个是中文ActionName_zh_CN.properties、一个是英文ActionName_en_US.properties。对于中文资源文件,需要特别注意:我们应使用Myeclipse自带的MyEclipse properties Editer编辑器来打开此资源文件,并在properties视图下进行编辑,这样它会把中文进行编码(我们切换到source视图下可以看到经编码后的中文)。 这一步非常重要,否则会出现乱码。
      可提供国际化资源文件的key值(FileUploadInterceptor中可查看)有:

    struts.messages.error.uploading - a general error that occurs when the file could not be uploaded
    struts.messages.error.file.too.large - occurs when the uploaded file is too large
    struts.messages.error.content.type.not.allowed - occurs when the uploaded file does not match the expected content types specified
    struts.messages.error.file.extension.not.allowed - occurs when the uploaded file does not match the expected file extensions specified
    ---------------------
    说明:
    怎么获取文件名称和文件类型呢?于是找了大量的资料发现:Strut2的Action类直接通过File类型属性直接封装了上传文件的文件内容,但这个File属性 无法获取上传文件的文件名和文件类型,所以Struts2就直接将文件域中包含的上传文件名和文件类型的信息封装到uploadFileName和 uploadContentType属性中,也就是说Struts2针对表单中名为xxx的文件域,在对应的Action类中使用3个属性来封装该文件域信息:
    l 类型为File的xxx属性:用来封装页面文件域对应的文件内容。
    l 类型为String的xxxFileName属性:用来封装该文件域对应的文件的文件名。
    l 类型为String的xxxContentType属性:用来封装该文件域应用的文件的文件类型。
     
     
    jsp页面
    <input type="file" id="upload" name="upload"/>  这个name就是与Action的属性对应
     
    Action类代码:
        
    [java] 
     
        private
     String uploadFileName;  
    •  String uploadContentType;  
    •       setUpload(File upload) {  
    • .upload = upload;  
    •     }  
    •   setUploadFileName(String uploadFileName) {  
    •         .uploadFileName = uploadFileName;  
    •   setUploadContentType(String uploadContentType) {  
    • .uploadContentType = uploadContentType;  
    •     }  
     
     
    设置3个属性。分别给set方法. 这样子,就能够获取上传的文件,文件名,文件类型。
     

    注意:这个uploadFileName,uploadContentType。如果File 属性名xxx(private File xxx;) 。那这个必须是xxxFileName, xxxContentType。然后也是分别给set 方法就可以。

    Struts2多文件上传

    页面:

    [html] 
     
     

    10.2 文件下载

    jsp页面中:

       
        <a href="fileDownload.action?fileName=aa11.jpg">下载文件</a>

    配置Struts文件:

    <action name="fileDownload" class="com.cn.action.FileOperAction"    method="getDownloadFile">
                        <result name="success" type="stream">
                                <!-- 设置contentType类型,并设置响应的编码类型为UTF-8 -->
                                <param name="contentType">application/x-msdownload;charset=UTF-8</param>
                                <param name="contentDisposition">attachment;fileName="${fileName}"</param>
                                <param name="inputName">downloadFileAsInputStream</param>
                                <param name="bufferSize">2048</param>
                        </result>
     </action>

    配置说明:

    当然这些参数都可以在<result type="stream">中配置 例如:

    <!-- 指定下载文件的文件类型,默认为text/plain -->
    <param name="contentType">Application/pdf</param>
    <!-- 指定由getDownloadFileAsInputStream()方法返回被下载文件的InputStream -->
    <param name="inputName">downloadFileAsInputStream</param>
    <!-- 下载对话框中显示下载的文件的名称 -->
    <param name="contentDisposition">attachment;fileName="${fileName}"</param>
    <!-- 指定下载文件的缓冲大小 -->
    <param name="bufferSize">2048</param>
    <!-- 是否支持缓存,默认为true -->
    <param name="allowCaching">true</param>

    Action中:
     public void setDownloadFileAsInputStream(InputStream downloadFileAsInputStream) {
      DownloadFileAsInputStream = downloadFileAsInputStream;
     }
     public InputStream getDownloadFileAsInputStream() {
      DownloadFileAsInputStream= ServletActionContext.getServletContext().getResourceAsStream("/files/"+fileName);
            
      return DownloadFileAsInputStream;
     }
    //
     public String getDownloadFile(){
      return SUCCESS;
      
     }

    学习参考:http://blog.csdn.net/leisure_life/article/details/57083523
    action也可以写如下:
    public class DownLoadAction {

        private InputStream inputStream;
        private String fileName;//文件名随意
        public InputStream getInputStream() {
            return inputStream;
        }
        public void setInputStream(InputStream inputStream) {
            this.inputStream = inputStream;
        }
        public String getFileName() {
            return fileName;
        }
        public void setFileName(String fileName) {
            this.fileName = fileName;
        }
        /** * * @return * @throws Exception * 这里强调一下:首先,在你的当前工程下先得存在/images这么个文件夹 * 其次里面得有一张叫0.bmp的图片 不然到哪里去下载(我们的代码是要放到服务器上去的) */
        public String execute() throws Exception{
            fileName = "0.bmp";
            inputStream = ServletActionContext.getServletContext().getResourceAsStream("/images/"+fileName);
            //设置下载文件名 别整中文哈 我这用的是UUID生成随机名字
            fileName = UUID.randomUUID()+".bmp";
            /* //如果实在是需要中文怎么办呢 fileName = "帅哥.jpg"; //先用当前编码将其打散 byte[] bytes = fileName.getBytes("utf-8"); //然后用服务端的编码组装起来 fileName = new String(bytes,"ISO-8859-1"); */
            return "success";
        }
    }
  • 相关阅读:
    软件工程——第十次作业
    第33次Scrum会议(11/21)【欢迎来怼】
    软件工程——第九次作业
    第26次Scrum会议(11/14)【欢迎来怼】
    软件工程——第八次作业
    psp总结报告
    第十二周psp
    第十一周psp
    探路者团队-贪吃蛇(测评人:刘耀泽)
    “Hello World!”团队第六周第七次会议
  • 原文地址:https://www.cnblogs.com/manmanlu/p/6962753.html
Copyright © 2020-2023  润新知