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(传统框架)。

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

相关推荐
n***84071 小时前
Spring Boot(七):Swagger 接口文档
java·spring boot·后端
v***5652 小时前
SpringBoot集成Flink-CDC,实现对数据库数据的监听
数据库·spring boot·flink
那我掉的头发算什么2 小时前
【javaEE】多线程 -- 超级详细的核心组件精讲(单例模式 / 阻塞队列 / 线程池 / 定时器)原理与实现
java·单例模式·java-ee
合作小小程序员小小店2 小时前
web网页开发,在线%图书管理%系统,基于Idea,html,css,jQuery,java,ssm,mysql。
java·前端·后端·mysql·jdk·intellij-idea
IUGEI2 小时前
【MySQL】SQL慢查询如何排查?从慢查询排查到最终优化完整流程
java·数据库·后端·mysql·go
程序员-周李斌3 小时前
Java NIO [非阻塞 + 多路复用解]
java·开发语言·开源软件·nio
程序猿小蒜3 小时前
基于Spring Boot的宠物领养系统的设计与实现
java·前端·spring boot·后端·spring·宠物
合作小小程序员小小店3 小时前
web网页开发,在线%食堂管理%系统,基于Idea,html,css,jQuery,java,ssm,mysql。
java·前端·mysql·html·intellij-idea·jquery
皮皮林5513 小时前
SpringBoot + Spring AI 玩转智能应用开发
spring boot