Struts2 文件上传

  • Struts2 文件上传简介
  • 单文件上传
    • 1 JSP
    • 2 Action
    • 3 相关说明
  • 多文件上传
    • 1 JSP
    • 2 Action
    • 3 相关说明
  • 常量配置说明

1. Struts2 文件上传简介

Struts2 的文件上传功能主要是通过 fileUpload 拦截器来实现的,此拦截器存在于 Struts2 的默认拦截器栈(defaultStack)中,对于自定义的 Action Package,默认继承 struts-default 包,此包为 Strut2 的默认 Action 包,其中已经配置了文件上传相关的拦截器栈,所以,通常情况下,无须关心文件上传的拦截器配置,它会自动装载。

另外,Struts2 并未提供自己的文件请求解析器,它需要调用其他上传框架来解析二进制请求数据,Struts2 只是在原有的基础上进行封装,简化了文件上传的实现。Strut2 默认使用 Jakarta 的 common-FileUpload 文件上传框架,依赖于 common-io 和 common-fileupload 两个 jar 包的支持,这两个 jar 包在 Struts2 的 lib 下有,直接添加到项目类路径下即可。同时,Struts2 还支持其他的文件上传框架,只需要在 Struts2 的配置文件中修改 struts.multipart.parser 参数并导入相关的支持 jar 文件即可,常见的文件上传框架还有 cos、pell 等。

2. 单文件上传

2.1 JSP

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<html>
<head>
<meta charset="UTF-8">
<title>File Upload Pagetitle>
head>
<body>
    <form action="${pageContext.request.contextPath}/fileupload/SingleFileUpload.action" method="post" enctype="multipart/form-data">
        <input type="file" name="upload">
        <input type="submit" value="上传">
    form>
body>
html>

2.2 Action

@Namespace("/fileupload")
public class SingleFileUpload extends ActionSupport {

    private File upload;
    private String uploadFileName;
    private String uploadContentType;
    private String savePath;

    @Action(value = "SingleFileUpload", params = { "savePath", "/WEB-INF/fileupload" }, results = {
            @Result(location = "/success.jsp") }, interceptorRefs = { @InterceptorRef(value = "defaultStack", params = {
                    "fileUpload.maximumSize", "1024*1024", "fileUpload.allowedTypes", "text/plain,image/jpg",
                    "fileUpload.allowedExtensions", "txt,jpg" }) })
    public String fileUpload() throws Exception {
        String fileName = getSavePath() + "/" + uploadFileName;

        FileOutputStream fileOutputStream = new FileOutputStream(fileName);
        FileInputStream fileInputStream = new FileInputStream(getUpload());

        byte[] b = new byte[1024];
        int len = 0;
        while ((len = fileInputStream.read(b)) > 0) {
            fileOutputStream.write(b, 0, len);
        }

        return SUCCESS;
    }

    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 String getUploadContentType() {
        return uploadContentType;
    }

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

    public String getSavePath() {
        return ServletActionContext.getServletContext().getRealPath(savePath);
    }

    public void setSavePath(String savePath) {
        this.savePath = savePath;
    }
}

2.3 相关说明

JSP:

  • form 表单属性
    • method:必须为 post 提交方式
    • enctype:必须为 multipart/form-data
  • input 元素
    • type:file,文件类型
    • name:此属性的值必须和 Action 中的 File 类型的属性的属性名完全一致

Action:

  • 主要属性:(属性是指 getter 和 setter 对应的属性名;另外,下面的 xxx 必须与 input 元素的 name 属性值完全一致)
    • File 类型属性 xxx,用来接收 form 表单提交过来的文件内容,但并不包括文件名和文件类型,所以需要下面两个属性
    • String 类型属性 xxxFileName,用来保存文件的文件名
    • String 类型属性 xxxContentType,用来保存文件的文件类型
  • Action 注解参数配置:(普通的 Action 配置此处不再说明)
    • savePath:传入参数,用来指定上传文件需要保存的路径,可以硬编码到程序中。注意:如果上传文件保存到当前项目路径下,那么当重新部署、发布项目时,由于新的发布文件中不存在之前的上传文件,一旦覆盖,上传文件会丢失。
    • interceptorRefs 拦截器配置,默认情况下,无须此配置,因为 Action 已经默认配置了 fileUpload 拦截器,不过此拦截器提供了文件上传的基本过滤,要使用此功能必须通过上述方式配置(注意属性的前缀,指明这些属性是配置给 defaultStack 栈中的 fileUpload 拦截器的),只有同时满足指定的所有过滤条件才能正确上传。
      • 文件大小 maximumSize 属性,指定单个文件的最大上传大小,单位为字节,此参数数据类型为 Long,在拦截器中只有 setMaximumSize(Long) 方法,而使用注解方式只能传入 String,所以在 Tomcat 启动时会出现异常 Warning,提示 java.lang.NoSuchMethodException:setMaximumSize(String),但可以正常运行。
      • 文件的 MIME 类型 allowedTypes,可以指定多个,用逗号隔开,限制上传的文件类型必须与此处列出的 MIME 类型对应
      • 文件的扩展名 allowedExtensions,可以指定多个,用逗号隔开,限制上传的文件扩展名必须是此处列出的扩展名之一

3. 多文件上传

3.1 JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head>
<meta charset="UTF-8">
<title>Multi-Files Upload Pagetitle>
head>
<body>
    <form action="${pageContext.request.contextPath}/fileupload/MultiFilesUpload.action" method="post" enctype="multipart/form-data">
        <input type="file" name="upload">
        <br>
        <input type="file" name="upload">
        <input type="submit" value="上传">
    form>
body>
html>

3.2 Action

@Namespace("/fileupload")
public class MultiFilesUpload extends ActionSupport {

    private static final long serialVersionUID = -3897278278212898252L;

    private File[] upload;
    private String[] uploadFileName;
    private String[] uploadContentType;

    @Action(value = "MultiFilesUpload", results = { @Result(location = "/success.jsp") })
    public String fileUpload() throws Exception {
        String uploadPath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/uploadfile");
        String fileName = null;

        for (int i = 0; i < upload.length; i++) {
            fileName = uploadPath + "/" + uploadFileName[i];
            FileUtils.copyFile(upload[i], new File(fileName));          
        }

        return SUCCESS;
    }

    public java.io.File[] getUpload() {
        return upload;
    }

    public void setUpload(java.io.File[] upload) {
        this.upload = upload;
    }

    public String[] getUploadFileName() {
        return uploadFileName;
    }

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

    public String[] getUploadContentType() {
        return uploadContentType;
    }

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

3.3 相关说明

多文件上传仅仅只是在单文件上传的基础上增加了页面 JSP 中的 input 元素的数量,在后台通过数组来接收多个文件及相关属性,其余语法基本一致,此处就没多做其他的配置。其中,在 JSP 页面中,采用的是多个 input 元素使用相同的 name 属性值来提交,所以对应的 Action 采用数组的形式来接收,如果 input 元素的 name 属性不一致,则需要在 Action 中使用多个 File 类型的属性来分别接收对应的上传文件,一般都使用前者。

4. 常量配置说明

对于 Struts2 的上传功能,除了前面提到的 struts.multipart.parser,主要还有 struts.multipart.saveDir 和 struts.multipart.maxSize 两个常量:

  • struts.multipart.saveDir:指定文件上传的临时目录,主要有以下四种情况(建议使用默认值或者绝对路径):

    • 不指定,即使用其默认值:此时通常会在 console 窗口看到如下信息:

      INFO: Unable to find ‘struts.multipart.saveDir’ property setting. Defaulting to javax.servlet.context.tempdir

      即默认使用 javax.servlet.context.tempdir 的值作为文件的临时上传目录,它对应的文件路径为 %TOMCAT_HOME%/work/Catalina/localhost/ProjectName

    • value = “temp”:此时使用 user.dir 的值作为文件的临时上传目录,user.dir 的值具体视环境而定,可通过 System.getPorperty(“user.dir”) 查看。
    • value = “/temp”:

      • Windows:网上说是当前工程所在盘的根目录下的 temp 文件夹下,未测试?
      • OS X 10.10:测试失败,提示

        SEVERE: Could not find create multipart save directory ‘/temp’.

        具体原因及解决办法未知,还望高手不吝赐教

    • value = “绝对路径”:本地磁盘的绝对路径
  • struts.multipart.maxSize:此处指定的是文件上传的整个请求内容允许的最大字节数,默认为 2M。注意:
    • 与单个文件上传大小的区分,且 Struts2 的上传控件会先使用此参数的值过滤所有上传文件的总大小,再使用过滤器中 maximumSize 参数指定的值对单个上传文件在大小进行过滤
    • 设置时,要确保此参数的值始终大于单个上传文件大小的设置值

你可能感兴趣的:(Struts2)