Ubuntu 22.04 安装 Apache Commons FileUpload 指南

在 Ubuntu 22.04 上从零安装 Apache Commons FileUpload 2.0.0-M5:JDK17 与 Maven 部署、官方 bin 包与 Maven 坐标两种方案、最小 multipart 上传验证与卸载清理。

Apache Commons FileUploadApache Commons FileUpload2026/10/14

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.xFileUpload 2.x
包名org.apache.commons.fileuploadorg.apache.commons.fileupload2
Servlet 依赖仅 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-core2.0.0-M5核心解析,必引
commons-fileupload2-jakarta-servlet52.0.0-M5Servlet 5.0(Tomcat 10.0/Jetty 11 等)
commons-fileupload2-jakarta-servlet62.0.0-M5Servlet 6.0(Tomcat 10.1/Jetty 12 等)
commons-fileupload2-javax2.0.0-M5兼容旧 javax.servlet(Tomcat 9 及以下)
commons-io2.21.02.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 包内 jarpom 中显式 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 应用。

十、参考链接

  1. Apache Commons FileUpload 官网:https://commons.apache.org/proper/commons-fileupload/
  2. 官方 bin 发布目录:https://downloads.apache.org/commons/fileupload/binaries/
  3. Maven Central 构件目录:https://repo1.maven.org/maven2/org/apache/commons/commons-fileupload2-core/
  4. FileUpload 2.0.0-M5 发布说明:https://downloads.apache.org/commons/fileupload/RELEASE-NOTES.txt
  5. Jakarta Servlet 规范:https://jakarta.ee/specifications/servlet/