跳至主要內容

Spring Boot + Multipart 文件上传:为什么你的应用在 10MB 后会失败

DD编辑部原创Spring BootSpring Boot大约 3 分钟

Spring Boot + Multipart 文件上传:为什么你的应用在 10MB 后会失败

说实话,文件上传问题是后端开发中最令人头疼的 bug 之一。我至今还记得第一次遇到 Spring Boot 应用拒绝上传大于 10MB 文件的情况。小文件上传一切正常,但当我尝试上传更大的文件时——砰!各种错误接踵而至。如果你也遇到过这种情况,相信我,你绝对不是一个人在战斗。

接下来我会详细解释问题的原因、解决方案,以及如何让你的 Spring Boot 应用顺利处理大文件上传。

问题一:"为什么超过 10MB 就报错?"

用户们愉快地上传头像和文档,一切都很顺利。直到有人尝试上传一个大约 12MB 的 PDF 文件,他们没有看到成功提示,而是收到了 "413 Payload Too Large" 错误。日志中显示:

org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException

当时想:"小文件明明可以正常上传,为什么大文件就不行了?"

经验总结: Spring Boot 默认将文件上传大小限制为 10MB。

问题二:如何解决上传限制?

经过一番搜索,我找到了解决方案:需要调整应用配置。在 application.propertiesapplication.yaml 中添加:

spring.servlet.multipart.max-file-size=50MB
spring.servlet.multipart.max-request-size=50MB

或者使用 YAML 格式:

spring:
  servlet:
    multipart:
      max-file-size: 50MB
      max-request-size: 50MB

配置完成后,50MB 以内的文件上传就能正常工作了。

经验总结: 你可以自由控制上传限制,只需要将配置属性调整为所需的大小即可。

问题三:"配置了还是不行,为什么?"

几周后,有用户尝试上传一个 20MB 的文件,应用又崩溃了,出现了奇怪的 "connection reset" 错误,后端没有明确的错误信息。这次我意识到问题出在服务器层面。如果你的 Spring Boot 应用运行在反向代理(如 Nginx 或 Apache)后面,这些服务器也有自己的文件大小限制。

对于 Nginx,需要设置:

client_max_body_size 50M;

对于 Apache,需要设置:

LimitRequestBody 52428800

解决这个问题后,文件上传终于对所有用户都正常工作了。

经验总结: 不仅仅是 Spring Boot 的问题——你的 Web 服务器或代理服务器也可能有文件大小限制。

问题四:上传大文件时出现 "OutOfMemoryError"

最后,我发现当有人尝试上传真正的大文件(比如 200MB)时,应用会因为 "OutOfMemoryError" 而崩溃。即使提高了文件大小限制,应用也无法正常处理。

解决方案很简单:

  • 保持文件大小限制在合理范围内。除非确实需要,否则不要让用户上传超大文件。
  • 直接将上传的文件保存到磁盘,而不是加载到内存中。使用流式处理open in new window

经验总结: 大文件上传会消耗服务器内存,需要谨慎处理!

核心要点

  • Spring Boot 有默认的文件大小限制(10MB)
  • 可以通过 application.propertiesapplication.yaml 提高限制
  • Web 服务器(如 Nginx 或 Apache)也有自己的限制——记得一并配置!
  • 对于超大文件,使用流式处理并注意内存使用情况

总结

如果你的文件上传在 10MB 后持续失败,不要慌张。检查你的 Spring Boot 配置、Web 服务器设置和内存使用情况。调整相关配置,并用真实文件进行测试。这样可以为你(和你的用户)节省大量的麻烦!

上次编辑于:
贡献者: didi