JSP 文件上传详解

【JSP 文件上传详解】——从入门到生产级实战(2026最新版) 📤

大家好!JSP 文件上传是 Web 开发中最常见的功能之一(头像、附件、Excel导入等)。本文从基础原理 → 两种主流实现方式 → 完整可运行代码 → 安全最佳实践,一步步带你彻底掌握。

支持 Tomcat 8+ / Servlet 3.0+,同时兼容传统 Commons FileUpload 方式。

1. 文件上传核心原理(必须先懂!)

  • HTML 表单必须设置:
  • method="post"
  • enctype="multipart/form-data"(普通 form-urlencoded 无法传输二进制文件)
  • 浏览器把文件拆分成多部分(multipart)发送
  • 服务器端需要解析 multipart 请求

两种主流解析方式(2026推荐):

方式依赖Servlet 版本复杂度推荐场景
@MultipartConfig + Part无(内置)3.0+★☆☆☆☆新项目(最推荐)
Apache Commons FileUploadcommons-fileupload + commons-io任意★★☆☆☆老项目、需要精细控制

2. 方式一:Servlet 3.0+ 原生方式(推荐,新项目直接用)

① upload.jsp(上传表单)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>JSP文件上传 - 原生方式</title>
</head>
<body>
    <h2>选择文件上传</h2>
    <form action="UploadServlet" method="post" enctype="multipart/form-data">
        选择文件: <input type="file" name="file" /><br/><br/>
        <input type="submit" value="上传" />
    </form>
</body>
</html>

② UploadServlet.java(核心处理)

import java.io.File;
import java.io.IOException;
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;

@WebServlet("/UploadServlet")
@MultipartConfig(
    fileSizeThreshold = 1024 * 1024 * 1,   // 超过1MB写临时文件
    maxFileSize = 1024 * 1024 * 10,        // 单个文件最大10MB
    maxRequestSize = 1024 * 1024 * 50      // 整个请求最大50MB
)
public class UploadServlet extends HttpServlet {
    private static final String UPLOAD_DIR = "uploads";

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 创建上传目录(应用根目录下)
        String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) uploadDir.mkdir();

        try {
            // 获取所有Part
            for (Part part : request.getParts()) {
                String fileName = getSubmittedFileName(part);
                if (fileName != null && !fileName.isEmpty()) {
                    // 保存文件
                    part.write(uploadPath + File.separator + fileName);
                    request.setAttribute("message", "上传成功!文件:" + fileName);
                }
            }
        } catch (Exception e) {
            request.setAttribute("message", "上传失败:" + e.getMessage());
        }

        // 跳转结果页
        request.getRequestDispatcher("/message.jsp").forward(request, response);
    }

    // Servlet 3.1+ 推荐方式获取文件名
    private String getSubmittedFileName(Part part) {
        for (String cd : part.getHeader("content-disposition").split(";")) {
            if (cd.trim().startsWith("filename")) {
                return cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
            }
        }
        return null;
    }
}

③ message.jsp(结果页)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>上传结果</title></head>
<body>
    <h2>${message}</h2>
    <a href="upload.jsp">继续上传</a>
</body>
</html>

访问:http://localhost:8080/你的项目/upload.jsp

3. 方式二:Apache Commons FileUpload(老项目/需要精细控制)

依赖(WEB-INF/lib 下放入):

  • commons-fileupload-1.5.0.jar(或最新)
  • commons-io-2.11.0.jar(或最新)

Servlet 代码与上面类似,但用 ServletFileUpload 解析(详见菜鸟教程或CodeJava示例,结构几乎一样,只是解析方式不同)。

4. 生产级最佳实践 & 安全重点(必须做!)

  1. 文件大小限制:必须设置 maxFileSizemaxRequestSize,防止 DoS 攻击。
  2. 文件名安全:不要直接用用户上传的名称!使用 UUID + 后缀。
   String safeName = UUID.randomUUID() + "_" + fileName;
  1. 文件类型校验:白名单(图片只允许 jpg/png/gif 等),最好再校验文件头(魔数)。
  2. 存储路径不要放在 web 根目录下!推荐 /var/uploads/ 或独立磁盘,防止直接访问。
  3. 权限控制:上传目录只给 Tomcat 用户写权限。
  4. 病毒扫描:生产环境接入 ClamAV 或商业杀毒。
  5. 大文件优化:异步上传 + 分片(秒传)可使用 WebUploader / Uploader.js 前端框架 + 后端支持。
  6. 中文文件名:设置 upload.setHeaderEncoding("UTF-8")

常见错误

  • 表单没加 enctype="multipart/form-data" → 取不到文件
  • 没配置 @MultipartConfig → 抛异常
  • 上传目录不存在或无写权限 → 失败

5. 扩展建议

  • 多文件上传multiple 属性 + 循环处理 getParts()
  • 进度条:前端用 XMLHttpRequest + Progress 事件
  • Spring Boot 项目:直接用 MultipartFile,比原生简单 10 倍
  • 漏洞防御:永远不要相信用户输入,参考“文件上传漏洞原理与防御”

立即动手

  1. 新建一个 Web 项目,复制上面代码运行
  2. 尝试上传图片、文本、超大文件,观察效果
  3. 修改文件名生成逻辑为 UUID

想看多文件上传完整版带进度条的前端+后端、还是Spring Boot 版本

直接评论回复 “1”“2”“3”,我下一篇文章立刻发完整代码仓库!

把这篇收藏起来 —— 文件上传功能一旦上线,就是真金白银的生产功能!💪

(本文基于 Servlet 3.1+、Apache Commons FileUpload 最新稳定版实测,兼容 Tomcat 9/10)

文章已创建 4992

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部