Struts 2 文件上传

Struts 2 框架为使用“HTML 中基于表单的文件上传”处理文件上传提供了内置支持。 上传文件时,它通常会存储在临时目录中,并且应该由 Action 类处理或移动到永久目录中,以确保数据不会丢失。

注意 - 服务器可能有一个安全策略,禁止我们写入临时目录和属于我们的 Web 应用程序的目录以外的目录。

Struts 中的文件上传可以通过一个称为 FileUpload 拦截器的预定义拦截器进行,该拦截器可通过 org.apache.struts2.interceptor.FileUploadInterceptor 类获得,并作为 defaultStack 的一部分包含在内。 我们仍然可以在 struts.xml 中使用它来设置各种参数,如下所示。

创建视图文件

让我们从创建浏览和上传所选文件所需的视图开始。 因此,让我们创建一个带有纯 HTML 上传表单的 index.jsp,允许用户上传文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
  <h1>Hello World From Struts2</h1>
  <form action = "upload" method = "post" enctype = "multipart/form-data">
    <label for = "myFile">上传文件</label>
    <input type = "file" name = "myFile" />
    <input type = "submit" value = "Upload"/>
  </form>
  </body>
</html>

在上面的例子中有几点值得注意。 首先,表单的 enctype 设置为 multipart/form-data。 应设置此值,从而使文件上传拦截器成功处理文件上传。 下一点要注意的是表单的操作方法 upload 和文件上传字段的名称 - myFile。 我们需要这些信息来创建 action 方法和 struts 配置。

接下来,让我们创建一个简单的 jsp 文件 success.jsp ,在Action 返回成功之后来显示我们的文件上传的结果。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传成功</title>
</head>
<body>
您的文件 <s:property value="myFileFileName" />已经上传
</body>
</html>

以下将是结果文件 error.jsp,在上传文件出现错误时显示。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传失败</title>
</head>
<body>
    上传文件时出现错误。
</body>
</html>

创建 Action 类

接下来,让我们创建一个名为 uploadFile.java 的 Java 类,它将负责上传文件并将该文件存储在安全位置

package com.jiyik.struts2.action;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public class UploadFile extends ActionSupport {
    private File myFile;
    private String myFileContentType;
    private String myFileFileName;
    private String destPath;

    @Override
    public String execute() {
        destPath = "/tmp/";

        try {
            System.out.println("原文件名为:" + myFile);
            System.out.println("新文件名为:" + myFileFileName);

            File destFile = new File(destPath, myFileFileName);
            FileUtils.copyFile(myFile, destFile);
        }catch (IOException e) {
            e.printStackTrace();
            return ERROR;
        }

        return SUCCESS;
    }

    public File getMyFile() {
        return myFile;
    }

    public String getMyFileContentType() {
        return myFileContentType;
    }

    public String getMyFileFileName() {
        return myFileFileName;
    }

    public void setMyFile(File myFile) {
        this.myFile = myFile;
    }

    public void setMyFileContentType(String myFileContentType) {
        this.myFileContentType = myFileContentType;
    }

    public void setMyFileFileName(String myFileFileName) {
        this.myFileFileName = myFileFileName;
    }
}

uploadFile.java 是一个非常简单的类。 需要注意的重要一点是 FileUpload 拦截器和参数拦截器为我们完成了所有繁重的工作。

FileUpload 拦截器默认为我们提供三个参数。 它们以以下模式命名

  • [您的文件名参数] - 这是用户上传的实际文件。 在此示例中,它将是“myFile”
  • [您的文件名参数]ContentType - 这是上传文件的内容类型。 在此示例中,它将是“myFileContentType”
  • [您的文件名参数]FileName - 这是上传文件的名称。 在此示例中,它将是“myFileFileName”

这三个参数可供我们使用,这要归功于 Struts 拦截器。 我们所要做的就是在我们的 Action 类中创建三个具有正确名称的参数,并自动为我们自动连接这些变量。 因此,在上面的示例中,我们有三个参数和一个操作方法,如果一切正常,则返回“succes”,否则返回“error”。

配置文件

以下是控制文件上传过程的 Struts2 配置属性

序号 属性 描述
1 struts.multipart.maxSize 允许上传的文件大小的最大值(以字节为单位)。 默认为 250M。
2 struts.multipart.parser 用于上传多部分表单的库。 默认是 jakarta
3 struts.multipart.saveDir 存储临时文件的位置。 默认情况下是 javax.servlet.context.tempdir

为了更改这些设置中的任何一个,我们可以在应用程序的 struts.xml 文件中使用常量标记,就像更改要上传的文件的最大大小一样。

我们的 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.devMode" value = "true" />
    <constant name = "struts.multipart.maxSize" value = "1000000" />

    <package name = "helloworld" extends = "struts-default">
        <action name = "upload" class = "com.jiyik.struts2.action.UploadFile">
            <result name = "success">/success.jsp</result>
            <result name = "error">/error.jsp</result>
        </action>
    </package>
</struts>

由于 FileUpload 拦截器是默认拦截器堆栈的一部分,我们不需要显式配置它。 但是,我们可以在 <action> 中添加 <interceptor-ref> 标签。 fileUpload 拦截器接受两个参数 (a) maximumSize(b) allowedTypes

maximumSize 参数设置允许的最大文件大小(默认值约为 2MB)。 allowedTypes 参数是以逗号分隔的可接受内容 (MIME) 类型列表,如下所示

<action name = "upload" class = "com.jiyik.struts2.action.UploadFile">
      <interceptor-ref name="fileUpload">
          <param name="allowdTypes">image/jpeg,image/gif</param>
          <param name="maximumSize">4096</param>
      </interceptor-ref>
      <result name = "success">/success.jsp</result>
      <result name = "error">/error.jsp</result>
</action>

以下是 web.xml 文件的内容

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

接下来我们验证上传文件的功能,首先使用 IDEA 启用项目,启动之后在浏览器中访问 http://localhost:8080,我们会看到如下的界面

Struts 文件上传界面

然后选择一个文件进行上传。

struts 文件上传成功界面

请注意,FileUpload 拦截器会自动删除上传的文件,因此我们必须以编程方式将上传的文件保存在某个位置,然后才能将其删除。

错误消息

fileUplaod 拦截器使用几个默认的错误消息键

序号 错误消息键 描述
1 struts.messages.error.uploading 无法上传文件时发生的一般错误。
2 struts.messages.error.file.too.large 当上传的文件过大时发生,由 maximumSize 指定。
3 struts.messages.error.content.type.not.allowed 当上传的文件与指定的预期内容类型不匹配时发生。

我们可以在 Web/WEB-INF/classes/messages.properties 资源文件中覆盖这些消息的文本。

查看笔记

扫码一下
查看教程更方便