Struts2之文件上传下载

一、文件上传

1、上传文件jsp页面

表单中enctype 必须为 multipart/form-data,提交方式必须为 post。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'fileupload.jsp' starting page</title> 
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
  </head>
  
  <body>
    <form action="fileupload_fileUpload.action" enctype="multipart/form-data" method="post">
        <s:if test="fieldErrors['upload'].size()>0">
            <s:property value="fieldErrors['upload'][0]"/>
        </s:if>
        <!-- 说明上传成功 -->
        <s:else>
            <p>
                <s:property value="message"/> <!-- 显示上传成功的提示信息 -->
                文件名:<s:property value="uploadFileName"/> <!-- 显示上传文件名 -->
                文件类型:<s:property value="uploadContentType"/> <!-- 显示上传文件类型 -->
            </p>
        </s:else>
        <p>
            上传者:<input type="text" name="author" class="ipt">
        </p>    
        <p>
            选择文件:<input type="file" name="upload" class="ipt">
        </p>
        <p><input type="submit" value="提交"> </p>
        
    </form>
  </body>
</html>

2、上传文件Action

对于name属性为xxx的文件,Action中需要用File类型的xxx封装上传的文件实例,用String类型的xxxFileName封装文件的名称,用xxxContent封装文件的文件类型。

package com.action;

import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class FileUploadAction extends ActionSupport {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private String message; // 提示信息
    private String author; // 上传者
    //需要提供get set方法才会封装进值
    private File upload; // Struts2会将上传成功的文件对象赋值给该属性
    private String uploadFileName; // 封装上传文件的名称,包括后缀
    private String uploadContentType; // 封装上传文件的类型

    
    public String fileUpload() throws Exception {
        // 保存文件的路径
        String realpath = ServletActionContext.getServletContext().getRealPath("/upload");
        System.out.println("文件路径" + realpath+"\n"+"文件类型:"+uploadContentType);
        // 未选择上传文件就提交的处理
        if (upload != null) {
            File savefile = new File(new File(realpath), uploadFileName);

            // 如果该文件所在目录不存在,则生成一个目录
            if (!savefile.getParentFile().exists()) {
                savefile.getParentFile().mkdirs();
            }
            FileUtils.copyFile(upload, savefile);
            
            ActionContext.getContext().put("msg", "上传文件成功");
        }else{
            ActionContext.getContext().put("msg", "请选择上传文件");
        }
        return "success";
    }
    
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public File getUpload() {
        return upload;
    }

    public void setUpload(File upload) {
        this.upload = upload;
    }

    public String getUploadFileName() {
        return uploadFileName;
    }

    public void setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    public String getUploadContentType() {
        return uploadContentType;
    }

    public void setUploadContentType(String uploadContentType) {
        this.uploadContentType = uploadContentType;
    }


}

3、struts.xml配置

如果不配置上传的文件大小,当所选文件过大时,会报错。

Struts2提供了一个文件上传的拦截器,配置拦截器时,可以为其指定两个参数:allowedTypes 和 maximumSize。

注意:其中常量里配置的文件上传大小是总的上传文件大小,拦截器中是单个上传文件大小。常量配置的允许大小,可视为总开关,不满足条件的大小将不会触发拦截且会报错。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "struts-2.3.dtd" >
<struts>

    <!-- 热部署 -->
    <constant name="struts.configuration.xml.reload" value="true"></constant>
    <!-- 修改struts2允许上传的最大值 -->
    <constant name="struts.multipart.maxSize" value="7097152"/>
    <!-- 动态方法调用 -->
    <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

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

        <action name="fileupload_*" class="com.action.FileUploadAction" method="{1}">
            <!-- 引入文件上传过滤器 -->
            <interceptor-ref name="fileUpload">
               <param name="maximumSize">7097152</param> <!-- 允许上传的单个文件大小 -->
               <param name="allowedTypes">image/bmp</param> <!-- 允许上传的文件类型,多个用,隔开 -->                
             </interceptor-ref>
             <!-- 配置系统默认拦截器 -->
             <interceptor-ref name="defaultStack"/>   
            <result name="input">/fileupload.jsp</result>  <!-- 文件过滤失败后,转入input视图 -->
            
             <result name="success">/fileupload.jsp</result>

        </action>
        
    </package>
</struts>   

常见问题:

当我们上传文件出错时,会出现Struts2系统默认的提示信息,这些信息,可以根据<s:debug>标签获取,为了获取更国际化的提示信息,例如,将提示信息改为中文。

操作步骤:

1、在struts.xml配置中加载全局国际化资源文件的常量

<constant name="struts.custom.i18n.resources" value="message"/>

2、在src目录下创建message.properties全国国际化文件,文件中添加如下内容

struts.messages.error.file.too.large=\u60A8\u8981\u4E0A\u4F20\u7684\u6587\u4EF6\u592A\u5927\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9

Struts2同时上传多个文件

Action类:

public class ManyFileUploadAction extends  ActionSupport{
     private  List<File>  upload;  //多文件封装为List
     private  List<String> uploadFileName;             
     public  String  manyFileUpload() throws Exception{
          for(int i=0;i<upload.size();i++){
              //处理每个文件上传的业务操作
     }
}

 二、文件下载

<a href="downLoad_downLoad.action?fileName=struts2学习笔记.txt">下载</a>
<a href="downLoad_downLoad.action?fileName=readme.txt">下载</a>  <!-- 下载至本地计算机中 -->
<a href="upload/readme.txt">下载</a>  <!-- 直接显示在网页中 -->

struts.xml配置:

<action name="downLoad_*" class="com.action.DownloadAction" method="{1}">
     <!-- 文件下载时返回类型必须为stream -->
     <result name="success" type="stream">
          <param name="contentDisposition">
              <!--
              attachment 表示浏览器以附件形式供下载  inline 表示内联方式
              ${fileName}表示获取DownLoadAction的fileName值
               -->
              attachment;filename="${fileName}"
           </param>
      <!-- <param name="inputName">
               InputStream
           </param> -->
      </result>
</action>

action类:

遗留问题:下载中文名称文件报错无法下载。

package com.action;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class DownloadAction extends ActionSupport{

    private String fileName;  // 要下载的文件名
    
    public String downLoad(){
        return "success";
    }
    
    /**
     * 返回类型必须为 InputStream
     * @return
     * @throws FileNotFoundException
     * @throws UnsupportedEncodingException 
     */
    public InputStream getInputStream() throws FileNotFoundException, UnsupportedEncodingException {
        System.out.println("文件名:"+getFileName());
        String path = ServletActionContext.getServletContext().getRealPath("/upload/"+fileName);
        System.out.println("下载路径:"+path);
        FileInputStream fis = new FileInputStream(path);
        return fis;
        
    }
    
    /**
     * 解决乱码问题
     * @return
     * @throws UnsupportedEncodingException
     */
    public String getFileName() throws UnsupportedEncodingException{
        return new String(this.fileName.getBytes(),"ISO8859-1");
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }


    
}

 

posted @ 2018-02-23 11:09  x_jingxin  阅读(144)  评论(0编辑  收藏  举报