Struts2 的文件上传功能依赖于 Apache Commons FileUpload 组件,Struts2 已经内置了对它的支持,所以我们只需要在项目中引入 Struts2 的核心依赖即可。

下面我将分步讲解整个过程,包括环境准备、JSP 页面编写、Action 类实现、struts.xml 配置以及最终部署测试。
第一步:环境准备
-
创建 Web 项目:在你的 IDE(如 Eclipse, IntelliJ IDEA)中创建一个动态 Web 项目。
-
添加 Struts2 依赖:将 Struts2 的核心 JAR 包添加到项目的
WEB-INF/lib目录中,如果你使用 Maven,可以直接在pom.xml中添加依赖。Maven 依赖 (
pom.xml):
(图片来源网络,侵删)<dependencies> <!-- Struts2 核心依赖 --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.33</version> <!-- 建议使用较新稳定版本 --> </dependency> <!-- 为了支持 JSP 视图,需要添加 struts2-convention-plugin 和 struts2-dojo-plugin (可选) --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-convention-plugin</artifactId> <version>2.5.33</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-dojo-plugin</artifactId> <version>2.5.33</version> </dependency> <!-- Servlet API (通常由 Web 容器提供,但为了编译通过,可以添加 provided 范围的依赖) --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> -
配置
web.xml:配置 Struts2 的核心过滤器StrutsPrepareAndExecuteFilter,它会拦截所有请求并交给 Struts2 框架处理。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"> <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>
第二步:创建上传页面 (JSP)
我们需要一个表单来选择文件并提交,注意,文件上传的表单必须满足两个条件:
method必须是post。enctype必须是multipart/form-data。
upload.jsp 文件内容:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>Struts2 文件上传</title>
</head>
<body>
<h2>请选择要上传的文件</h2>
<s:form action="upload" method="post" enctype="multipart/form-data">
<!--
s:file 标签用于创建文件上传输入框
name 属性必须与 Action 中对应的属性名一致
-->
<s:file name="myFile" label="选择文件"></s:file>
<!-- 可以添加其他普通文本输入框 -->
<s:textfield name="description" label="文件描述"></s:textfield>
<s:submit value="上传"></s:submit>
</s:form>
</body>
</html>
第三步:创建 Action 类处理上传
Action 类是 Struts2 的核心,负责接收请求、处理业务逻辑并返回结果,对于文件上传,Action 类需要:
- 为
<s:file>标签的name属性提供一个对应的属性(myFile),并生成getter和setter,这个属性的类型是org.apache.commons.io.FileUtils中的File。 - 为文件名提供一个属性(
myFileFileName),并生成getter和setter,这个属性的类型是String。 - 类型提供一个属性(
myFileContentType),并生成getter和setter,这个属性的类型是String。 - 在
execute方法中,将接收到的文件从临时目录移动到你指定的服务器目录。
UploadAction.java 文件内容:
package com.example.action;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import java.io.File;
import java.io.IOException;
public class UploadAction {
// 1. 对应 <s:file name="myFile"> 的属性
private File myFile;
// 2. 对应文件名的属性 (由 Struts2 自动生成)
private String myFileFileName;
// 3. 对应文件类型的属性 (由 Struts2 自动生成)
private String myFileContentType;
// 4. 其他普通字段
private String description;
// 上传文件的目标目录 (放在 Web 根目录下的 upload 文件夹)
private static final String UPLOAD_DIR = ServletActionContext.getServletContext().getRealPath("/upload");
public String execute() {
// 确保上传目录存在
File uploadDir = new File(UPLOAD_DIR);
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
try {
// 创建目标文件对象
File destFile = new File(UPLOAD_DIR, myFileFileName);
// 使用 FileUtils.copyFile 将上传的临时文件复制到目标位置
// 这比直接使用 File.renameTo() 更可靠,因为它不受跨文件系统限制
FileUtils.copyFile(myFile, destFile);
System.out.println("文件上传成功!");
System.out.println("文件名: " + myFileFileName);
System.out.println("文件类型: " + myFileContentType);
System.out.println("文件描述: " + description);
System.out.println("文件保存在: " + destFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
// 如果上传失败,可以返回一个错误结果
return "error";
}
return "success";
}
// --- 以下是必须的 Getter 和 Setter ---
public File getMyFile() {
return myFile;
}
public void setMyFile(File myFile) {
this.myFile = myFile;
}
public String getMyFileFileName() {
return myFileFileName;
}
public void setMyFileFileName(String myFileFileName) {
this.myFileFileName = myFileFileName;
}
public String getMyFileContentType() {
return myFileContentType;
}
public void setMyFileContentType(String myFileContentType) {
this.myFileContentType = myFileContentType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
第四步:配置 struts.xml
我们需要在 src 目录下创建 struts.xml 文件,配置 UploadAction 的映射。
struts.xml 文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!-- 开发模式下,会重新加载配置文件,方便调试 -->
<constant name="struts.devMode" value="true" />
<!-- 设置上传文件的大小限制 (默认是 2MB) -->
<!-- 单位是字节,这里是 10MB -->
<constant name="struts.multipart.maxSize" value="10485760" />
<package name="default" namespace="/" extends="struts-default">
<!--
配置文件上传的 Action
name="upload" 对应 JSP 表单的 action="upload"
class="com.example.action.UploadAction" 指定我们编写的 Action 类
-->
<action name="upload" class="com.example.action.UploadAction">
<!--
result name="success" 表示 execute 方法返回 "success" 时要跳转的页面
我们跳转到 success.jsp,并显示上传成功信息
-->
<result name="success">/success.jsp</result>
<!--
result name="error" 表示 execute 方法返回 "error" 时要跳转的页面
我们跳转到 error.jsp,显示错误信息
-->
<result name="error">/error.jsp</result>
</action>
</package>
</struts>
第五步:创建成功和失败页面
为了完善流程,我们创建两个简单的页面来显示上传结果。
success.jsp 文件内容:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>上传成功</title>
</head>
<body>
<h2>文件上传成功!</h2>
<p>文件名: <s:property value="myFileFileName"/></p>
<p>文件类型: <s:property value="myFileContentType"/></p>
<p>文件描述: <s:property value="description"/></p>
<p>文件已保存在服务器: <s:property value="uploadDir"/>/<s:property value="myFileFileName"/></p>
<!-- 注意:这里的 uploadDir 需要在 Action 中提供 getter -->
</body>
</html>
error.jsp 文件内容:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>上传失败</title>
</head>
<body>
<h2 style="color: red;">文件上传失败!</h2>
<p>请检查文件大小或类型是否正确,然后重试。</p>
</body>
</html>
第六步:部署和测试
- 部署项目:将项目部署到你的 Web 服务器(如 Tomcat)。
- 启动服务器。
- 访问页面:在浏览器中访问
http://localhost:8080/你的项目名/upload.jsp。 - 选择文件并上传:选择一个文件,填写描述,点击“上传”按钮。
- 查看结果:
- 如果成功,页面会跳转到
success.jsp,并显示文件信息。 - 如果失败(例如文件过大),页面会跳转到
error.jsp。
- 如果成功,页面会跳转到
- 验证文件:去你 Web 应用的根目录下,检查是否多了一个名为
upload的文件夹,里面是否包含了你上传的文件。
总结与注意事项
- 属性命名:Struts2 会根据
<s:file name="myFile">自动创建myFile(File对象)、myFileFileName(文件名)和myFileContentType(文件类型)这三个属性。命名规则是固定的,不能随意更改。 - 临时文件:上传的文件首先会保存在服务器的临时目录中(Tomcat 的
work目录下)。execute方法执行完毕后,这个临时文件会被自动删除,你必须在execute方法中将其复制或移动到永久位置。 - 文件大小限制:可以通过
struts.xml中的<constant name="struts.multipart.maxSize" value="..."/>来配置允许上传的最大文件大小(单位是字节)。 - 安全性:在生产环境中,你需要对上传的文件进行严格的校验,
- 文件类型:检查
myFileContentType或文件后缀,防止上传.exe,.jsp等危险文件。 - 文件名:对文件名进行重命名或过滤,防止路径遍历攻击(如
../../malicious.jsp)。 - 病毒扫描:对上传的文件进行病毒扫描。
- 文件类型:检查
