Ubuntu 22.04 安装 Apache Commons FileUpload 指南
在 Ubuntu 22.04 上从零安装 Apache Commons FileUpload 2.0.0-M5:JDK17 与 Maven 部署、官方 bin 包与 Maven 坐标两种方案、最小 multipart 上传验证与卸载清理。
Ubuntu 22.04 安装 Apache Commons FileUpload 指南
目标:在 Ubuntu 22.04 服务器上从零搭建 Apache Commons FileUpload 2.x 可用环境(JDK17 + Maven + 官方 bin 包 / Maven 坐标两种引入方式),并跑通 multipart 表单文件上传的最小验证,已在 Ubuntu 22.04.5 服务器实测通过。
一、环境信息
本节列出文档实测的服务器基础信息,便于读者对照自身环境。
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- JDK:OpenJDK 17.0.20.1(apt 安装,路径
/usr/lib/jvm/java-17-openjdk-amd64) - 构建工具:Apache Maven 3.6.3(apt 安装,
/usr/share/maven) - 组件版本:Apache Commons FileUpload 2.0.0-M5(
commons-fileupload2-core+commons-fileupload2-jakarta-servlet5) - 依赖:commons-io 2.21.0、jakarta.servlet-api 5.0.0(编译期 provided)、Jetty 11.0.26(仅验证 Servlet 场景用)
- 下载源:downloads.apache.org(bin 包与 sha512)、repo1.maven.org(Maven 坐标)
- 实验目录:
/opt/fu-lab(bin 包解压与源码示例目录)、/opt/fu-lab/jetty-demo(Maven 工程目录)
二、前置条件
本节说明安装 FileUpload 之前需要先准备好的环境要素。
FileUpload 2.x 是 Java 库,本身没有安装进程,所谓"安装"实际是:装好 JDK 与构建工具 → 把 commons-fileupload2-* 的 jar 引入工程(bin 包直引或 Maven 坐标拉取)→ 编译运行最小上传程序验证可用。
2.1 更新软件源
执行以下命令刷新 apt 索引,保证后续安装到的包为仓库最新版本:
apt-get update
实测回显(末尾输出节选):
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Hit:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Reading package lists Done
2.2 安装 JDK 17
FileUpload 2.0.0-M5 官方要求 Java 11 及以上,本指南统一采用 JDK 17(LTS):
apt-get install -y openjdk-17-jdk
验证安装结果:
java -version
实测回显:
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
2.3 安装 Maven
Maven 用于第二种安装方案(Maven 坐标自动拉取依赖):
apt-get install -y maven curl unzip
验证 Maven 版本:
mvn -version
实测回显:
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "6.8.0-138-generic", arch: "amd64", family: "unix"
💡 技术拓展:Maven 依赖管理方案不止一种。常见对比——
方案 特点 适用场景 Maven 坐标 pom.xml 声明 groupId/artifactId/version,自动下载传递依赖 主流 Java 工程 Gradle 坐标 build.gradle 声明,语法更简洁 新一代构建体系 手工 jar 管理 下载 jar 放入 lib 目录,javac -cp 引用 无构建工具的老式工程 本文两种安装方案分别采用「官方 bin 包直引 jar」与「Maven 坐标」,前者适合离线环境,后者适合常规工程开发。
三、版本选型说明
本节说明当前各版本情况与本文选定的版本。
3.1 版本现状与坐标拆分
Apache Commons FileUpload 自 2.0.0 起拆分为多个构件:commons-fileupload2-core(核心解析逻辑,不依赖 Servlet API)与 commons-fileupload2-jakarta-* / commons-fileupload2-javax(Servlet 集成层,按 Servlet 规范命名空间区分)。
💡 技术拓展:FileUpload 1.x 与 2.x 的核心差异——
维度 FileUpload 1.x FileUpload 2.x 包名 org.apache.commons.fileuploadorg.apache.commons.fileupload2Servlet 依赖 仅 javax.servlet 拆 jakarta.servlet5 / jakarta.servlet6 / javax 多构件 工厂构造 new DiskFileItemFactory()DiskFileItemFactory.builder().get()构建器FileItem 取文件名 getFileName()getName()大小上限参数 setSizeMax/setFileSizeMaxsetMaxSize/setMaxFileSize本文实测采用 FileUpload 2.x(2.0.0-M5),因为它是当前 Apache 官网发布的最新主线,且 2.x 已随 Jakarta EE 全面迁移。
3.2 官方发布目录实测
在 downloads.apache.org 的 commons/fileupload/binaries/ 目录下确认最新版本(2026 年实测):
curl -s https://downloads.apache.org/commons/fileupload/binaries/ | grep -oE 'href="[^"]+\.tar\.gz"' | sort -u
实测回显(输出节选):
href="commons-fileupload-1.6.0-bin.tar.gz"
href="commons-fileupload2-2.0.0-M5-bin.tar.gz"
可见 2.x 最新发布为 2.0.0-M5(M 后缀为里程碑版本,非正式 GA;同时存在 1.6.0 为 1.x 遗留线)。
3.3 Maven Central 坐标版本
核对 Maven Central 上各构件的可用版本:
curl -s https://repo1.maven.org/maven2/org/apache/commons/commons-fileupload2-core/maven-metadata.xml | grep -E '<(latest|release)>'
curl -s https://repo1.maven.org/maven2/org/apache/commons/commons-fileupload2-jakarta-servlet5/maven-metadata.xml | grep -E '<(latest|release)>'
实测回显:
<latest>2.0.0-M5</latest>
<release>2.0.0-M5</release>
<latest>2.0.0-M5</latest>
<release>2.0.0-M5</release>
⚠️ 注意:早期构件名
commons-fileupload2-jakarta在 Maven Central 上仅发布到 2.0.0-M1(2023-07 后停止),2.0.0-M5 的 Jakarta 集成层已改名为commons-fileupload2-jakarta-servlet5(对应 Servlet 5.0)与commons-fileupload2-jakarta-servlet6(对应 Servlet 6.0),引入依赖时切勿再用旧名。
3.4 版本选型结论
| 构件 | 版本 | 说明 |
|---|---|---|
| commons-fileupload2-core | 2.0.0-M5 | 核心解析,必引 |
| commons-fileupload2-jakarta-servlet5 | 2.0.0-M5 | Servlet 5.0(Tomcat 10.0/Jetty 11 等) |
| commons-fileupload2-jakarta-servlet6 | 2.0.0-M5 | Servlet 6.0(Tomcat 10.1/Jetty 12 等) |
| commons-fileupload2-javax | 2.0.0-M5 | 兼容旧 javax.servlet(Tomcat 9 及以下) |
| commons-io | 2.21.0 | 2.x 运行期传递依赖 |
本文统一选用 2.0.0-M5 + Jakarta Servlet 5.0 组合(对应 Jetty 11 与 Tomcat 10.0 等主流 Servlet 5 服务器)。
四、方案 A:官方 bin 包安装(离线直引 jar)
本节介绍从 Apache 官网下载 bin 发布包、校验 sha512、直引 jar 编译运行的最小方案,适合内网/离线服务器。
4.1 下载 bin 包与 sha512 校验文件
mkdir -p /opt/fu-lab && cd /opt/fu-lab
curl -LO https://downloads.apache.org/commons/fileupload/binaries/commons-fileupload2-2.0.0-M5-bin.tar.gz
curl -LO https://downloads.apache.org/commons/fileupload/binaries/commons-fileupload2-2.0.0-M5-bin.tar.gz.sha512
ls -la
实测回显(输出节选):
-rw-r--r-- 1 root root 1309645 Oct 13 17:59 commons-fileupload2-2.0.0-M5-bin.tar.gz
-rw-r--r-- 1 root root 129 Oct 13 17:59 commons-fileupload2-2.0.0-M5-bin.tar.gz.sha512
4.2 校验 sha512 完整性
将下载文件与官方 .sha512 逐字节比对:
cat commons-fileupload2-2.0.0-M5-bin.tar.gz.sha512
sha512sum commons-fileupload2-2.0.0-M5-bin.tar.gz
实测回显:
7e050be0187813dfa6fac3e9679a9be71a7956a97ff3e8e762ad2fd5552f3883ecfbe92c013c2f66409a998600c7167d8749eecbdf61ba50f69472af8a9ec533
7e050be0187813dfa6fac3e9679a9be71a7956a97ff3e8e762ad2fd5552f3883ecfbe92c013c2f66409a998600c7167d8749eecbdf61ba50f69472af8a9ec533 commons-fileupload2-2.0.0-M5-bin.tar.gz
两行哈希完全一致,校验通过。
4.3 解压并确认 jar 构件
tar xzf commons-fileupload2-2.0.0-M5-bin.tar.gz
ls commons-fileupload2-2.0.0-M5/ | grep -E '\.jar$'
实测回显(输出节选):
commons-fileupload2-core-2.0.0-M5.jar
commons-fileupload2-jakarta-servlet5-2.0.0-M5.jar
commons-fileupload2-jakarta-servlet6-2.0.0-M5.jar
commons-fileupload2-javax-2.0.0-M5.jar
commons-fileupload2-portlet-2.0.0-M5.jar
bin 包同时包含 core 与各 Servlet 变体,无需区分下载。
4.4 准备运行期依赖 jar
2.x 的 DiskFileItemFactory 继承自 commons-io 的 AbstractStreamBuilder,运行期需要 commons-io。从 Maven Central 下载:
mkdir -p /opt/fu-lab/deps && cd /opt/fu-lab/deps
curl -LO https://repo1.maven.org/maven2/commons-io/commons-io/2.21.0/commons-io-2.21.0.jar
curl -LO https://repo1.maven.org/maven2/jakarta/servlet/jakarta.servlet-api/5.0.0/jakarta.servlet-api-5.0.0.jar
ls -la
实测回显(输出节选):
-rw-r--r-- 1 root root 585274 Oct 13 18:02 commons-io-2.21.0.jar
-rw-r--r-- 1 root root 307850 Oct 13 18:02 jakarta.servlet-api-5.0.0.jar
4.5 编写最小 multipart 解析程序并编译运行
编写一个直接解析本地构造的 multipart/form-data 请求体的验证程序(不依赖任何 Web 服务器,仅用 core 的 FileItemFactory):
// /opt/fu-lab/src/FileUpload2CoreDemo.java
import org.apache.commons.fileupload2.core.AbstractFileUpload;
import org.apache.commons.fileupload2.core.DiskFileItem;
import org.apache.commons.fileupload2.core.DiskFileItemFactory;
import org.apache.commons.fileupload2.core.FileItemInputIterator;
import org.apache.commons.fileupload2.core.RequestContext;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
public class FileUpload2CoreDemo {
public static void main(String[] args) throws Exception {
String boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW";
String body = "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"author\"\r\n\r\n"
+ "Apache Commons FileUpload 2.0.0-M5\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"report\"; filename=\"demo.txt\"\r\n"
+ "Content-Type: text/plain\r\n\r\n"
+ "hello from commons-fileupload2-core\r\n"
+ "--" + boundary + "--\r\n";
byte[] bytes = body.getBytes(StandardCharsets.UTF_8);
RequestContext ctx = new RequestContext() {
public String getCharacterEncoding() { return "UTF-8"; }
public long getContentLength() { return bytes.length; }
public String getContentType() { return "multipart/form-data; boundary=" + boundary; }
public InputStream getInputStream() { return new ByteArrayInputStream(bytes); }
public boolean isMultipartRelated() { return false; }
};
DiskFileItemFactory factory = DiskFileItemFactory.builder().get();
AbstractFileUpload<Object, DiskFileItem, DiskFileItemFactory> upload = new AbstractFileUpload<>() {
public FileItemInputIterator getItemIterator(Object request) { throw new UnsupportedOperationException(); }
public Map<String, List<DiskFileItem>> parseParameterMap(Object request) { throw new UnsupportedOperationException(); }
public List<DiskFileItem> parseRequest(Object request) { throw new UnsupportedOperationException(); }
};
upload.setFileItemFactory(factory);
List<DiskFileItem> items = upload.parseRequest(ctx);
System.out.println("Parsed FileItem count: " + items.size());
for (DiskFileItem item : items) {
System.out.println(" fieldName=" + item.getFieldName()
+ " | isFormField=" + item.isFormField()
+ " | fileName=" + item.getName()
+ " | contentType=" + item.getContentType()
+ " | value=" + item.getString(StandardCharsets.UTF_8));
}
}
}
编译并运行(classpath 包含 core jar 与 commons-io):
mkdir -p /opt/fu-lab/out
javac -encoding UTF-8 -cp "/opt/fu-lab/commons-fileupload2-2.0.0-M5/commons-fileupload2-core-2.0.0-M5.jar:/opt/fu-lab/deps/commons-io-2.21.0.jar" -d /opt/fu-lab/out /opt/fu-lab/src/FileUpload2CoreDemo.java
java -cp "/opt/fu-lab/out:/opt/fu-lab/commons-fileupload2-2.0.0-M5/commons-fileupload2-core-2.0.0-M5.jar:/opt/fu-lab/deps/commons-io-2.21.0.jar" FileUpload2CoreDemo
实测回显:
Parsed FileItem count: 2
fieldName=author | isFormField=true | fileName=null | contentType=null | value=Apache Commons FileUpload 2.0.0-M5
fieldName=report | isFormField=false | fileName=demo.txt | contentType=text/plain | value=hello from commons-fileupload2-core
解析出 2 个 FileItem:普通表单字段 author(isFormField=true)与文件字段 report(isFormField=false,文件名 demo.txt,内容回显正确),multipart 解析链路验证通过。
💡 说明:
FileItemFactory是 2.x 的核心抽象,负责把解析出的每个 part 包装成FileItem;DiskFileItemFactory是其默认实现(小文件驻内存、超阈值写临时文件)。1.x 中同名工厂用普通构造器,2.x 改用builder()构建器。
五、方案 B:Maven 坐标安装(在线工程引入)
本节介绍在标准 Maven 工程中通过坐标引入 FileUpload 2.x,并用嵌入式 Jetty 起最小 Servlet + curl -F 实测真实 HTTP 上传。
5.1 创建 Maven 工程与 pom.xml
mkdir -p /opt/fu-lab/jetty-demo/src/main/java/upload
cd /opt/fu-lab/jetty-demo
pom.xml 关键依赖(坐标均已在 3.3 节实测确认):
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-fileupload2-jakarta-servlet5</artifactId>
<version>2.0.0-M5</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>11.0.26</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>11.0.26</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
逐项说明:commons-fileupload2-jakarta-servlet5 会自动带入 commons-fileupload2-core 与 commons-io 传递依赖;jetty-server/jetty-servlet 提供嵌入式 Servlet 服务器;jakarta.servlet-api 为编译期接口,provided 表示 Web 服务器运行期自带。
5.2 编写上传 Servlet 与启动类
上传 Servlet 使用 JakartaServletDiskFileUpload(2.x Jakarta 集成层的开箱即用类):
// /opt/fu-lab/jetty-demo/src/main/java/upload/UploadServlet.java
package upload;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload2.core.DiskFileItem;
import org.apache.commons.fileupload2.core.DiskFileItemFactory;
import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletDiskFileUpload;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/plain; charset=UTF-8");
PrintWriter out = response.getWriter();
try {
DiskFileItemFactory factory = DiskFileItemFactory.builder().get();
JakartaServletDiskFileUpload upload = new JakartaServletDiskFileUpload(factory);
upload.setMaxSize(1024L * 1024 * 10); // 整请求上限 10 MB
upload.setMaxFileSize(1024L * 1024 * 5); // 单文件上限 5 MB
List<DiskFileItem> items = upload.parseRequest(request);
out.println("Parsed FileItem count: " + items.size());
for (DiskFileItem item : items) {
out.println(" fieldName=" + item.getFieldName()
+ " | isFormField=" + item.isFormField()
+ " | fileName=" + item.getName()
+ " | contentType=" + item.getContentType()
+ " | size=" + item.getSize()
+ " | value=" + item.getString(StandardCharsets.UTF_8));
}
} catch (Exception e) {
out.println("ERROR: " + e.getClass().getName() + ": " + e.getMessage());
}
}
}
嵌入式 Jetty 启动类:
// /opt/fu-lab/jetty-demo/src/main/java/upload/UploadServer.java
package upload;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class UploadServer {
public static void main(String[] args) throws Exception {
Server server = new Server(18080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet(new ServletHolder(new UploadServlet()), "/upload");
server.setHandler(context);
server.start();
System.out.println("Jetty started on http://0.0.0.0:18080/upload");
server.join();
}
}
5.3 构建工程(Maven 自动拉取依赖)
cd /opt/fu-lab/jetty-demo && mvn -q -DskipTests package
echo $?
实测回显:
0
Maven 从 repo1.maven.org 自动拉取 fileupload2-core、fileupload2-jakarta-servlet5、commons-io 等依赖并完成打包,退出码 0 表示成功。
5.4 启动 Jetty 并实测 curl -F 上传
生成依赖 classpath 后启动(JVM 堆限定 256MB,见 §3.6 规范):
cd /opt/fu-lab/jetty-demo
mvn -q dependency:build-classpath -Dmdep.outputFile=cp.txt
nohup java -Xms256m -Xmx256m -cp "target/classes:$(cat cp.txt)" upload.UploadServer > /opt/fu-lab/jetty.log 2>&1 &
sleep 6
tail -2 /opt/fu-lab/jetty.log
实测回显:
Jetty started on http://0.0.0.0:18080/upload
Jetty 11.0.26 已在 18080 端口监听。构造带文件字段与普通字段的 multipart 请求实测:
printf "hello from jetty curl -F upload test\nline2: multipart parsing ok\n" > /opt/fu-lab/REPORT.txt
curl -s http://127.0.0.1:18080/upload -F "author=Apache Commons FileUpload 2.0.0-M5" -F "report=@/opt/fu-lab/REPORT.txt;type=text/plain"
实测回显:
Parsed FileItem count: 2
fieldName=author | isFormField=true | fileName=null | contentType=null | size=34 | value=Apache Commons FileUpload 2.0.0-M5
fieldName=report | isFormField=false | fileName=REPORT.txt | contentType=text/plain | size=65 | value=hello from jetty curl -F upload test
line2: multipart parsing ok
curl -F 发送的真实 HTTP multipart 请求被 Servlet 完整解析:普通字段 author 的值、文件字段 REPORT.txt 的文件名(REPORT.txt)、类型(text/plain)、字节数(65)与文件内容全部正确回显,方案 B 验证通过。
六、方案对比与选择建议
本节对两种安装方案做横向对比并给出选型建议。
| 维度 | 方案 A:官方 bin 包 | 方案 B:Maven 坐标 |
|---|---|---|
| 是否需联网 | 下载一次后可离线使用 | 每次构建需访问 Maven 仓库(可配私服) |
| 依赖管理 | 手工下载 commons-io 等运行期依赖 | 坐标自动带入传递依赖 |
| 工程适配 | 适用于无构建工具/老式工程 | 标准 Maven/Gradle 工程 |
| 版本锁定 | 固定 bin 包内 jar | pom 中显式 version 锁定 |
| 升级方式 | 重新下载替换 jar | 改 version 重新构建 |
| 适用场景 | 内网隔离、审计严苛的生产服务器 | 日常开发、CI/CD |
选型建议:可联网的常规工程优先方案 B(依赖自动管理、升级方便);内网隔离服务器或需要严格离线审计的场景选方案 A(bin 包 sha512 可验证、构件清单透明)。两种方案产出的 jar 完全相同,可在同一工程内混用。
七、配置说明
本节说明 FileUpload 2.x 关键参数的设置位置与默认值(完整参数逐项解读见《Apache Commons FileUpload 配置参数详解》篇)。
- DiskFileItemFactory.builder().setThreshold(10240):文件内容超过 10240 字节(10 KB)时写入磁盘临时文件,默认即 10 KB;
setRepository(Path)指定临时目录。 - upload.setMaxSize(long):整个请求体上限,默认 -1(不限制)。
- upload.setMaxFileSize(long):单个文件上限,默认 -1(不限制)。
- upload.setMaxFileCount(long):单请求文件个数上限,默认 -1(不限制)。
- upload.setHeaderCharset(Charset):解析 part 头时的字符集,默认 null(回退请求编码,再回退平台默认)。
- upload.setMaxPartHeaderSize(int):单个 part 头部大小上限,默认 512 字节。
八、常见问题
Q1:编译或运行时出现 NoSuchMethodError: FileUtils.getTempDirectoryPath() 怎么解决?
定位:这是 classpath 里混入了旧版 commons-io(如 1.4,其 FileUtils 没有该方法),而 DiskFileItemFactory 需要较新的 commons-io。
解决:清理工程依赖目录中残留的旧 commons-io,统一使用 2.21.0(或更高);Maven 工程用 mvn dependency:build-classpath 生成的 classpath,不要手工把整个本地仓库目录拼进 -cp。实测修复后 Jetty 正常返回解析结果。
Q2:commons-fileupload2-jakarta 坐标拉不下来或版本只有 M1?
定位:该旧构件名在 Maven Central 仅发布到 2.0.0-M1。
解决:改用 commons-fileupload2-jakarta-servlet5(Servlet 5.0)或 commons-fileupload2-jakarta-servlet6(Servlet 6.0),2.0.0-M5 起官方按 Servlet 版本拆分构件名。
Q3:javac 编译带中文输出时提示 unmappable character for encoding US-ASCII?
定位:服务器 locale 为 POSIX(ASCII),javac 默认按平台编码解析源码。
解决:编译时加 -encoding UTF-8(示例均采用),或将源码内中文改为英文输出。
Q4:上传超过限制后抛什么异常?
定位:超限会抛 org.apache.commons.fileupload2.core.FileUploadSizeException(继承 FileUploadException)。
实测(setMaxSize=1000,实际 20104 字节):
FileUploadSizeException: the request was rejected because its size (20104) exceeds the configured maximum (1000)
可通过异常的 getPermitted()/getActualSize() 获取上限与实际大小后返回友好的 413 响应。
九、卸载与清理
本节说明如何移除本指南安装的环境(按需执行)。
- 删除验证工程与下载产物:
rm -rf /opt/fu-lab
- 卸载 JDK 与 Maven(如需彻底移除):
apt-get remove -y openjdk-17-jdk maven
- 清理 Maven 本地仓库(可选,删除后下次构建需重新下载依赖):
rm -rf /root/.m2/repository
⚠️ 说明:FileUpload 本身是 jar 库,卸载即删除工程中的依赖声明与本地 jar;以上卸载步骤不影响其他 Java 应用。
十、参考链接
- Apache Commons FileUpload 官网:https://commons.apache.org/proper/commons-fileupload/
- 官方 bin 发布目录:https://downloads.apache.org/commons/fileupload/binaries/
- Maven Central 构件目录:https://repo1.maven.org/maven2/org/apache/commons/commons-fileupload2-core/
- FileUpload 2.0.0-M5 发布说明:https://downloads.apache.org/commons/fileupload/RELEASE-NOTES.txt
- Jakarta Servlet 规范:https://jakarta.ee/specifications/servlet/