文件上传后端(别再被文件上传坑了!Java实现文件上传,附避坑指南(亲测有效))

文件上传后端(别再被文件上传坑了!Java实现文件上传,附避坑指南(亲测有效))
别再被文件上传坑了!Java实现文件上传,附避坑指南(亲测有效)

作者:不想打工的码农
标签:#Java #SpringBoot #文件上传 #后端开发 #实战技巧

大家好,我是老张。

上周三晚上10点,手机突然响了。
客户在电话那头急得直拍桌子:“老张!用户传个合同,系统直接报500!明天就要签单了啊!”

我赶紧远程连上服务器——
日志里赫然一行:org.apache.tomcat.util.http.fileupload.FileUploadBase $ SizeLimitExceededException: the request was rejected because its size exceeds the configured maximum

文件上传后端(别再被文件上传坑了!Java实现文件上传,附避坑指南(亲测有效))

又是文件大小限制!

这已经是我今年第4次处理同类问题。
今天,我就把血泪总结的文件上传三板斧掏出来,手把手教你从0搭一个稳当的上传功能,连实习生都能看懂!


第一步:配置别乱改!认准这3个参数

很多教程让你改application.properties,但改错位置等于白改!

正确配置(Spring Boot 2.7+)

# 单个文件最大10MB(注意单位!)spring.servlet.multipart.max-file-size=10MB# 整个请求最大20MB(多个文件总和)spring.servlet.multipart.max-request-size=20MB# 上传超时时间(防大文件卡死)spring.servlet.multipart.request-timeout=30s

⚠️ 血泪坑

  • 用spring.http.multipart?那是Spring Boot 1.x的老写法!2.x已废弃!
  • 单位写成10M?必须带B(10MB),否则启动直接报错!
  • 改完不重启?配置不会生效!(别笑,真有同事栽过)

第二步:Controller写法(带校验!)

直接上干货代码:

@PostMapping("/upload")public Result<String> uploadFile(@RequestParam("file") MultipartFile file) {    // 1. 空文件校验    if (file.isEmpty()) {        return Result.error(400, "文件不能为空");    }        // 2. 类型校验(只允许PDF/Word)    String originalFilename = file.getOriginalFilename();    String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();    if (!Arrays.asList("pdf", "doc", "docx").contains(ext)) {        return Result.error(400, "仅支持PDF、Word文档上传");    }        // 3. 大小二次校验(防前端绕过)    if (file.getSize() > 10 * 1024 * 1024) { // 10MB        return Result.error(400, "文件大小不能超过10MB");    }        // 4. 保存文件(关键!路径处理)    String savePath = "/data/uploads/" + System.currentTimeMillis() + "_" + originalFilename;    try {        File dest = new File(savePath);        // 确保目录存在        if (!dest.getParentFile().exists()) {            dest.getParentFile().mkdirs();        }        file.transferTo(dest);        return Result.ok("上传成功,路径:" + savePath);    } catch (IOException e) {        log.error("文件保存失败", e);        return Result.error(500, "服务器异常,请重试");    }}

为什么校验写两遍?

  • 前端校验能被绕过(F12改代码)
  • 后端校验是最后防线,必须做!

第三步:前端配合(超简单)

<form id="uploadForm" enctype="multipart/form-data">  <input type="file" name="file" accept=".pdf,.doc,.docx" required>  <button type="submit">上传</button></form><script>document.getElementById('uploadForm').onsubmit = function(e) {  e.preventDefault();  const fileInput = this.querySelector('input[type="file"]');  const file = fileInput.files[0];    // 前端预校验(提升体验)  if (file.size > 10 * 1024 * 1024) {    alert("文件不能超过10MB!");    return;  }    const formData = new FormData(this);  fetch('/api/upload', {    method: 'POST',    body: formData  })  .then(res => res.json())  .then(data => alert(data.msg))  .catch(err => alert("上传失败"));};</script>

关键细节

  • accept属性限制可选文件类型(但后端仍需校验!)
  • 用FormData原生提交,不依赖jQuery
  • 前端预校验提升用户体验,减少无效请求

避坑指南(全是实战踩出来的)

❌ 坑1:中文文件名乱码

现象:上传“合同_张三.pdf",保存成“????.pdf"
解决

// 保存前对文件名编码(Linux服务器必加!)String safeName = URLEncoder.encode(originalFilename, "UTF-8").replace("+", "%20");

❌ 坑2:Linux服务器没写入权限

现象:本地跑得好好的,上服务器就报Permission denied
解决

# 上传前执行(给目录授权)chmod -R 755 /data/uploadschown -R www:www /data/uploads  # 改成你的运行用户

❌ 坑3:大文件上传超时

现象:传50MB文件,30秒后前端报“网络错误”
解决(三处都要改!):

# application.propertiesspring.servlet.multipart.request-timeout=300s# Nginx配置(/etc/nginx/conf.d/xxx.conf)client_max_body_size 100M;proxy_read_timeout 300s;

❌ 坑4:路径写死导致迁移困难

最佳实践

// 从配置读路径(方便不同环境切换)@Value(" $ {file.upload.path:/data/uploads}")private String uploadPath;

最后说两句

文件上传看着简单,但90%的线上事故都出在细节上

  • 忘了二次校验 → 被传木马
  • 路径没处理 → 服务器被写满
  • 权限没配 → 客户急得跳脚

记住老张的话:

“前端校验是礼貌,后端校验是底线。”

把这三步做扎实,下次客户再打电话,你就能淡定回一句:
“稍等,我喝口茶就处理好。”


我是「不想打工的码农」,一个在代码和生活间找平衡的普通开发者。
觉得有用?点赞收藏防走丢!
评论区聊聊:你被文件上传坑过最惨的一次是啥?

#Java##SpringBoot##文件上传##后端开发##程序员避坑##不想打工的码农#程序员##职场##2026如何提振消费#

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有

相关阅读