JavaWeb 文件上传全方案解析:从传统组件到现代框架实现

在 JavaWeb 开发中,文件上传是核心功能之一,不同的技术栈和开发场景对应不同的实现方式。本文将全面讲解JavaWeb 中所有主流的文件上传方式 ,包括传统 Commons FileUpload 组件Servlet 3.0 原生上传Spring MVC 上传Spring Boot 上传(单文件 / 多文件、本地 / 云存储),并提供逐行注释的完整代码,确保零基础也能掌握每种方式的实现逻辑。

一、文件上传的基础前提

无论使用哪种实现方式,文件上传的HTTP 协议基础要求是统一的:

  1. 表单提交方式必须为POST
  2. 表单的enctype属性必须设置为multipart/form-data(默认application/x-www-form-urlencoded无法传输二进制文件);
  3. 表单中通过<input type="file" name="xxx">标签选择文件,多文件上传添加multiple属性。

前端通用上传表单(upload.html):

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>文件上传通用表单</title>
</head>
<body>
    <h3>单文件上传</h3>
    <form action="对应后端接口路径" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="username"><br><br>
        选择文件:<input type="file" name="file"><br><br>
        <input type="submit" value="上传">
    </form>

    <h3>多文件上传</h3>
    <form action="对应后端接口路径" method="post" enctype="multipart/form-data">
        选择多个文件:<input type="file" name="files" multiple><br><br>
        <input type="submit" value="批量上传">
    </form>
</body>
</html>

二、方式一:传统 Commons FileUpload 组件(Servlet 2.5 及以下)

这是Servlet 3.0 之前的主流实现方式 ,依赖 Apache 的commons-fileuploadcommons-io两个 jar 包,适用于老旧项目。

2.1 环境准备

Maven 依赖
XML 复制代码
<!-- 文件上传核心依赖 -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
<!-- 依赖的IO工具包 -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.15.1</version>
</dependency>
<!-- ServletAPI依赖(Tomcat已提供,设为provided) -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
非 Maven 项目

手动下载 jar 包放入WEB-INF/lib

2.2 后端实现(单 / 多文件上传)

java 复制代码
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * Commons FileUpload实现文件上传(支持单/多文件)
 */
@WebServlet("/commonsUpload")
public class CommonsFileUploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置编码,解决中文乱码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        // 1. 判断请求是否为multipart/form-data类型
        if (!ServletFileUpload.isMultipartContent(request)) {
            response.getWriter().write("请求不是文件上传类型,请检查表单enctype!");
            return;
        }

        try {
            // 2. 创建文件上传工厂,设置临时目录和内存阈值
            DiskFileItemFactory factory = new DiskFileItemFactory();
            String tempPath = this.getServletContext().getRealPath("/temp"); // 临时目录
            File tempDir = new File(tempPath);
            if (!tempDir.exists()) tempDir.mkdirs(); // 不存在则创建
            factory.setRepository(tempDir); // 设置临时文件存储目录
            factory.setSizeThreshold(1024 * 1024); // 1MB内存阈值,超过则写入临时文件

            // 3. 创建文件上传核心处理类
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setFileSizeMax(5 * 1024 * 1024); // 单个文件最大5MB
            upload.setSizeMax(20 * 1024 * 1024); // 总文件最大20MB
            upload.setHeaderEncoding("UTF-8"); // 文件名编码

            // 4. 解析请求,将表单项封装为FileItem列表
            List<FileItem> fileItems = upload.parseRequest(request);

            // 5. 遍历处理每个表单项
            for (FileItem item : fileItems) {
                if (item.isFormField()) {
                    // 处理普通表单字段(如用户名)
                    String fieldName = item.getFieldName();
                    String fieldValue = item.getString("UTF-8");
                    System.out.println("普通字段:" + fieldName + " = " + fieldValue);
                } else {
                    // 处理文件字段(单/多文件统一处理)
                    handleFile(item, request);
                }
            }

            response.getWriter().write("文件上传成功!");
        } catch (FileUploadException e) {
            e.printStackTrace();
            response.getWriter().write("上传失败:" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("服务器异常:" + e.getMessage());
        }
    }

    /**
     * 处理文件上传的核心方法
     * @param item 文件项
     * @param request 请求对象
     * @throws Exception 异常
     */
    private void handleFile(FileItem item, HttpServletRequest request) throws Exception {
        // 获取原始文件名(处理IE浏览器的完整路径问题)
        String originalFileName = item.getName();
        if (originalFileName != null && originalFileName.contains("\\")) {
            originalFileName = originalFileName.substring(originalFileName.lastIndexOf("\\") + 1);
        }
        // 未选择文件则直接返回
        if (originalFileName == null || originalFileName.trim().isEmpty()) return;

        // 生成唯一文件名,防止覆盖
        String uniqueFileName = UUID.randomUUID().toString() + "_" + originalFileName;

        // 获取上传目标目录
        String uploadPath = this.getServletContext().getRealPath("/upload");
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) uploadDir.mkdirs();

        // 保存文件到服务器
        File saveFile = new File(uploadDir, uniqueFileName);
        item.write(saveFile);

        // 删除临时文件(超大文件会生成临时文件)
        item.delete();

        // 输出文件信息
        System.out.println("原始文件名:" + originalFileName);
        System.out.println("保存文件名:" + uniqueFileName);
        System.out.println("保存路径:" + saveFile.getAbsolutePath());
    }
}

三、方式二:Servlet 3.0 原生上传(无第三方依赖)

Servlet 3.0 及以上版本提供了原生的文件上传 API ,无需引入第三方 jar 包,通过Part接口实现文件上传,是轻量级项目的首选。

3.1 核心 API 说明

  • request.getPart(String name):获取单个文件的 Part 对象;
  • request.getParts():获取所有 Part 对象(多文件上传);
  • Part.write(String fileName):将文件写入服务器;
  • Part.getSubmittedFileName():获取上传文件的原始名称。

3.2 后端实现(单 / 多文件上传)

java 复制代码
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * Servlet 3.0原生文件上传
 * @MultipartConfig:必须添加该注解,开启文件上传支持
 * 配置参数说明:
 * - fileSizeThreshold:内存阈值(1MB)
 * - maxFileSize:单个文件最大大小(5MB)
 * - maxRequestSize:总请求大小(20MB)
 * - location:临时文件存储目录
 */
@WebServlet("/nativeUpload")
@MultipartConfig(
        fileSizeThreshold = 1024 * 1024,
        maxFileSize = 5 * 1024 * 1024,
        maxRequestSize = 20 * 1024 * 1024,
        location = "/temp"
)
public class NativeFileUploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置编码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        // 1. 处理普通表单字段(如用户名)
        String username = request.getParameter("username");
        System.out.println("普通字段:username = " + username);

        try {
            // 2. 单文件上传处理(name为file的文件)
            Part singleFilePart = request.getPart("file");
            if (singleFilePart != null && singleFilePart.getSize() > 0) {
                handlePart(singleFilePart, request);
            }

            // 3. 多文件上传处理(name为files的文件)
            for (Part part : request.getParts()) {
                if ("files".equals(part.getName()) && part.getSize() > 0) {
                    handlePart(part, request);
                }
            }

            response.getWriter().write("Servlet 3.0原生上传成功!");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("上传失败:" + e.getMessage());
        }
    }

    /**
     * 处理Part对象,保存文件到服务器
     * @param part 文件Part对象
     * @param request 请求对象
     * @throws IOException 异常
     */
    private void handlePart(Part part, HttpServletRequest request) throws IOException {
        // 获取原始文件名
        String originalFileName = part.getSubmittedFileName();
        if (originalFileName == null || originalFileName.trim().isEmpty()) return;

        // 生成唯一文件名
        String uniqueFileName = UUID.randomUUID().toString() + "_" + originalFileName;

        // 获取上传目录
        String uploadPath = this.getServletContext().getRealPath("/upload");
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) uploadDir.mkdirs();

        // 保存文件(Part的write方法自动处理IO,无需手动流操作)
        part.write(uploadPath + File.separator + uniqueFileName);

        // 输出文件信息
        System.out.println("原始文件名:" + originalFileName);
        System.out.println("保存文件名:" + uniqueFileName);
        System.out.println("文件大小:" + part.getSize() + "字节");
    }
}

关键注解@MultipartConfig是 Servlet 3.0 原生上传的核心,必须添加,否则无法获取Part对象。

四、方式三:Spring MVC 文件上传(基于 Servlet 3.0)

Spring MVC 对 Servlet 3.0 的文件上传进行了封装和简化 ,通过MultipartFile接口实现文件上传,是企业级 JavaWeb 项目的主流方式。

4.1 环境准备

Maven 依赖
XML 复制代码
<!-- Spring MVC核心依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.30</version>
</dependency>
<!-- ServletAPI依赖 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
<!-- 文件上传依赖(Spring MVC封装用) -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
Spring MVC 配置(xml 方式)

spring-mvc.xml中配置文件上传解析器:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 组件扫描,扫描Controller -->
    <context:component-scan base-package="com.controller"/>

    <!-- 开启MVC注解驱动 -->
    <mvc:annotation-driven/>

    <!-- 配置文件上传解析器,id必须为multipartResolver -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"/> <!-- 编码 -->
        <property name="maxUploadSizePerFile" value="5242880"/> <!-- 单个文件5MB -->
        <property name="maxUploadSize" value="20971520"/> <!-- 总文件20MB -->
        <property name="uploadTempDir" value="WEB-INF/temp"/> <!-- 临时目录 -->
    </bean>
</beans>

4.2 后端 Controller 实现

java 复制代码
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * Spring MVC文件上传Controller
 */
@Controller
public class SpringMvcUploadController {

    /**
     * 单文件上传
     * @param username 普通表单字段
     * @param file 上传的文件(name必须与前端input的name一致)
     * @param request 请求对象
     * @return 上传结果
     */
    @PostMapping("/springMvcSingleUpload")
    @ResponseBody
    public String singleUpload(String username, MultipartFile file, HttpServletRequest request) {
        // 处理普通字段
        System.out.println("普通字段:username = " + username);

        // 判断是否选择文件
        if (file.isEmpty()) {
            return "请选择要上传的文件!";
        }

        try {
            handleMultipartFile(file, request);
            return "Spring MVC单文件上传成功!";
        } catch (IOException e) {
            e.printStackTrace();
            return "上传失败:" + e.getMessage();
        }
    }

    /**
     * 多文件上传
     * @param files 多文件数组(name必须与前端input的name一致)
     * @param request 请求对象
     * @return 上传结果
     */
    @PostMapping("/springMvcMultiUpload")
    @ResponseBody
    public String multiUpload(MultipartFile[] files, HttpServletRequest request) {
        // 判断是否选择文件
        if (files == null || files.length == 0) {
            return "请选择要上传的文件!";
        }

        // 遍历处理每个文件
        for (MultipartFile file : files) {
            if (!file.isEmpty()) {
                try {
                    handleMultipartFile(file, request);
                } catch (IOException e) {
                    e.printStackTrace();
                    return "批量上传失败:" + e.getMessage();
                }
            }
        }

        return "Spring MVC多文件上传成功!";
    }

    /**
     * 处理MultipartFile,保存文件到服务器
     * @param file 上传的文件
     * @param request 请求对象
     * @throws IOException 异常
     */
    private void handleMultipartFile(MultipartFile file, HttpServletRequest request) throws IOException {
        // 获取原始文件名
        String originalFileName = file.getOriginalFilename();
        // 生成唯一文件名
        String uniqueFileName = UUID.randomUUID().toString() + "_" + originalFileName;

        // 获取上传目录
        ServletContext servletContext = request.getServletContext();
        String uploadPath = servletContext.getRealPath("/upload");
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) uploadDir.mkdirs();

        // 保存文件(transferTo方法自动处理IO)
        File saveFile = new File(uploadDir, uniqueFileName);
        file.transferTo(saveFile);

        // 输出文件信息
        System.out.println("原始文件名:" + originalFileName);
        System.out.println("保存文件名:" + uniqueFileName);
        System.out.println("文件大小:" + file.getSize() + "字节");
    }
}

五、方式四:Spring Boot 文件上传(最简实现)

Spring Boot 对 Spring MVC 的文件上传进行了自动配置,无需手动配置文件上传解析器,是目前最主流的实现方式,支持本地存储和云存储(如阿里云 OSS)。

5.1 环境准备

Maven 依赖(Spring Boot 2.7.x)
XML 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.15</version>
    <relativePath/>
</parent>

<dependencies>
    <!-- Spring Boot Web依赖(自动包含文件上传相关封装) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
配置文件(application.yml)
XML 复制代码
spring:
  # 文件上传配置
  servlet:
    multipart:
      enabled: true # 开启文件上传
      default-encoding: UTF-8 # 编码
      max-file-size: 5MB # 单个文件最大大小
      max-request-size: 20MB # 总请求最大大小
      location: ./temp # 临时文件目录
# 自定义上传目录(非必须,也可在代码中硬编码)
upload:
  path: ./upload # 本地存储目录(项目根目录下的upload文件夹)

5.2 本地存储实现(单 / 多文件)

java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * Spring Boot文件上传(本地存储)
 */
@RestController
public class SpringBootUploadController {

    // 从配置文件中读取上传目录
    @Value("${upload.path}")
    private String uploadPath;

    /**
     * 单文件上传
     * @param username 普通表单字段
     * @param file 上传的文件
     * @return 上传结果
     */
    @PostMapping("/bootSingleUpload")
    public String singleUpload(String username, MultipartFile file) {
        System.out.println("普通字段:username = " + username);
        if (file.isEmpty()) {
            return "请选择文件!";
        }
        try {
            saveFile(file);
            return "Spring Boot单文件上传成功!";
        } catch (IOException e) {
            e.printStackTrace();
            return "上传失败:" + e.getMessage();
        }
    }

    /**
     * 多文件上传
     * @param files 多文件数组
     * @return 上传结果
     */
    @PostMapping("/bootMultiUpload")
    public String multiUpload(MultipartFile[] files) {
        if (files == null || files.length == 0) {
            return "请选择文件!";
        }
        for (MultipartFile file : files) {
            if (!file.isEmpty()) {
                try {
                    saveFile(file);
                } catch (IOException e) {
                    e.printStackTrace();
                    return "批量上传失败:" + e.getMessage();
                }
            }
        }
        return "Spring Boot多文件上传成功!";
    }

    /**
     * 保存文件到本地
     * @param file 上传的文件
     * @throws IOException 异常
     */
    private void saveFile(MultipartFile file) throws IOException {
        // 获取原始文件名
        String originalFileName = file.getOriginalFilename();
        // 生成唯一文件名
        String uniqueFileName = UUID.randomUUID().toString() + "_" + originalFileName;

        // 创建上传目录
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) uploadDir.mkdirs();

        // 保存文件
        File saveFile = new File(uploadDir, uniqueFileName);
        file.transferTo(saveFile);

        // 输出文件信息
        System.out.println("原始文件名:" + originalFileName);
        System.out.println("保存路径:" + saveFile.getAbsolutePath());
    }
}

5.3 云存储实现(阿里云 OSS 示例)

实际项目中,文件通常不会存储在服务器本地(易丢失、占用服务器磁盘),而是上传到云存储服务(如阿里云 OSS、腾讯云 COS)。以下是 Spring Boot 集成阿里云 OSS 的文件上传实现:

5.3.1 阿里云 OSS 依赖(更建议依据官方SDK文档进行)
XML 复制代码
<!-- 阿里云OSS SDK -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.17.0</version>
</dependency>
5.3.2 阿里云 OSS 配置(application.yml)
XML 复制代码
aliyun:
  oss:
    endpoint: oss-cn-beijing.aliyuncs.com # OSS地域节点
    access-key-id: 你的AccessKeyId # 阿里云AccessKey
    access-key-secret: 你的AccessKeySecret # 阿里云AccessKeySecret
    bucket-name: 你的Bucket名称 # OSS存储空间名称
5.3.3 OSS 工具类
java 复制代码
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.UUID;

/**
 * 阿里云OSS文件上传工具类
 */
@Component
public class AliOssUtil {

    @Value("${aliyun.oss.endpoint}")
    private String endpoint;

    @Value("${aliyun.oss.access-key-id}")
    private String accessKeyId;

    @Value("${aliyun.oss.access-key-secret}")
    private String accessKeySecret;

    @Value("${aliyun.oss.bucket-name}")
    private String bucketName;

    /**
     * 上传文件到阿里云OSS
     * @param file 上传的文件
     * @return 文件的访问URL
     * @throws Exception 异常
     */
    public String upload(MultipartFile file) throws Exception {
        // 获取原始文件名
        String originalFileName = file.getOriginalFilename();
        // 生成唯一文件名
        String objectName = UUID.randomUUID().toString() + "_" + originalFileName;

        // 创建OSS客户端
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 获取文件输入流
            InputStream inputStream = file.getInputStream();
            // 上传文件到OSS
            ossClient.putObject(bucketName, objectName, inputStream);
            // 生成文件访问URL
            return "https://" + bucketName + "." + endpoint + "/" + objectName;
        } finally {
            // 关闭OSS客户端
            ossClient.shutdown();
        }
    }
}
5.3.4 OSS 上传 Controller
java 复制代码
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

/**
 * Spring Boot集成阿里云OSS文件上传
 */
@RestController
public class AliOssUploadController {

    @Resource
    private AliOssUtil aliOssUtil;

    @PostMapping("/ossUpload")
    public String ossUpload(MultipartFile file) {
        if (file.isEmpty()) {
            return "请选择文件!";
        }
        try {
            String fileUrl = aliOssUtil.upload(file);
            return "阿里云OSS上传成功,文件URL:" + fileUrl;
        } catch (Exception e) {
            e.printStackTrace();
            return "OSS上传失败:" + e.getMessage();
        }
    }
}

六、各上传方式对比与适用场景

实现方式 依赖 优点 缺点 适用场景
Commons FileUpload 第三方 jar 包 兼容老旧 Servlet 版本 代码繁琐、依赖第三方 Servlet 2.5 及以下老旧项目
Servlet 3.0 原生 轻量级、无依赖 代码冗余、需手动处理细节 轻量级 Servlet 项目(3.0+)
Spring MVC Spring MVC+Commons FileUpload 封装性好、企业级标准 需手动配置解析器 传统 Spring MVC 项目
Spring Boot 本地存储 Spring Boot Web 自动配置、代码极简 仅本地存储,易丢失 小型项目、测试环境
Spring Boot 云存储 Spring Boot + 云存储 SDK 高可用、易扩展、不占服务器磁盘 需购买云服务 生产环境、企业级项目

七、常见问题与通用解决方案

  1. 中文乱码:设置请求 / 响应编码为 UTF-8,文件上传组件的默认编码也设为 UTF-8;
  2. 文件覆盖:使用 UUID、时间戳生成唯一文件名;
  3. 文件大小限制:在组件 / 配置中设置最大文件大小,捕获超限异常;
  4. 文件类型限制 :判断文件后缀名或 MIME 类型(如file.getContentType().startsWith("image/"));
  5. 临时文件残留:上传完成后手动删除临时文件(Commons FileUpload)或依赖框架自动清理。

八、总结

本文覆盖了 JavaWeb 中所有主流的文件上传方式,从传统的 Commons FileUpload 组件到现代的 Spring Boot 云存储,每种方式都提供了完整的代码实现和注释。在实际开发中,应根据项目的技术栈(Servlet 版本、是否使用 Spring)和部署环境(测试 / 生产)选择合适的实现方式:

  • 老旧项目选Commons FileUpload
  • 轻量级 Servlet 项目选Servlet 3.0 原生
  • 企业级项目优先选Spring Boot + 云存储 (生产环境)或Spring MVC(传统框架)。

掌握这些方式后,可轻松应对用户头像上传、附件管理、图片服务器等实际业务场景的文件上传需求!

相关推荐
咩咩啃树皮2 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
鱟鲥鳚3 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
大模型码小白4 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司5 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地6 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun3141596 小时前
TCP超时重传机制是为了解决什么问题?
java
莫逸风8 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
隔窗听雨眠9 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
z123456789869 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin52112310 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python