解决 SpringBoot 上传文件超过 5MB 返回 404 的问题
问题描述
最近遇到了一个比较棘手的问题:测试同学反馈说外地一位用户在使用特定设备发送用户反馈时,自动上传日志附件的功能总是返回 404 错误,而其他设备和其他用户都没有问题。
这个问题初看起来像是路由问题或者特定设备兼容性问题,但经过排查发现,实际上是由于上传的日志文件大小超过了后端 SpringBoot 配置的文件大小限制导致的。
问题排查过程
1. 初步排查
收到问题反馈后,我首先进行了以下排查:
- 检查客户端代码:确认上传逻辑是否有问题,特别是针对特定设备的处理
- 本地测试:在我的开发环境下,使用 curl 命令模拟上传请求,测试正常
- 测试环境验证:测试同学也在他的环境下用 curl 测试,同样没有问题
|
|
2. 联系后端和运维排查
由于本地测试都正常,我开始怀疑是服务端的问题,于是联系了:
- 运维同学:检查 Nginx 等反向代理配置,确认没有大小限制
- 服务端开发:检查接口路由和日志,发现请求根本没有到达后端 Controller
3. 远程排查找到根因
最终通过远程连接到问题用户的电脑,检查实际上传的文件时发现:
- 问题文件大小:8MB
- 后端配置限制:单文件最大 5MB,总请求限制 50MB
原来问题出在这里!用户上传的日志文件是 8MB,超过了后端配置的单文件 5MB 限制。当文件超过限制时,SpringBoot 会在请求到达 Controller 之前就拒绝请求,直接返回 404 错误,而不是返回更友好的"文件过大"错误提示。
4. 为什么本地测试没问题?
本地测试时使用的测试文件都比较小(通常小于 1MB),所以没有触发这个限制。而实际用户生成的日志文件可能因为使用时长、日志级别等原因,文件较大,超过了 5MB 的限制。
解决方案
临时解决方案
由于这是后端配置的限制,我采取了以下临时措施:
- 客户端文件大小检查:在上传前检查文件大小,如果超过 5MB,提示用户文件过大,建议压缩或分段上传
- 日志文件压缩:对于较大的日志文件,在上传前进行压缩处理,减少文件大小
- 日志文件分段:如果文件过大,可以考虑将日志文件分段上传
根本解决方案(需要后端配合)
这个问题需要后端同学调整 SpringBoot 的文件上传大小限制配置。以下是几种常见的配置方式,供后端同学参考:
方案一:在 application.yml 中配置(推荐)
在 application.yml 或 application.properties 中添加以下配置:
|
|
如果使用 application.properties:
|
|
方案二:在代码中配置 MultipartConfigElement
如果需要在代码中动态配置,可以创建一个配置类:
|
|
问题总结
这次排查让我学到了几个重要的经验:
-
404 不一定是路由问题:当文件超过 SpringBoot 配置的大小限制时,请求会在到达 Controller 之前就被拒绝,返回 404 错误,而不是更友好的错误提示。
-
本地测试的局限性:本地测试环境可能无法完全复现生产环境的问题,特别是文件大小、网络环境等因素。需要尽可能模拟真实场景,或者直接到问题现场排查。
-
跨团队协作的重要性:这类问题需要客户端、服务端、运维等多个团队协作排查,及时沟通可以更快定位问题。
-
客户端防御性编程:应该在上传前进行文件大小检查,给用户友好的提示,而不是让用户看到莫名其妙的 404 错误。
延伸思考:SpringBoot 文件上传配置
对于后端开发同学,如果需要调整文件上传大小限制,可以参考以下配置方式:
配置说明
SpringBoot 对文件上传有以下关键配置:
spring.servlet.multipart.max-file-size: 单个文件最大大小,默认值为 1MBspring.servlet.multipart.max-request-size: 整个请求的最大大小,默认值为 10MB
当上传的文件超过这些限制时,SpringBoot 会在请求到达 Controller 之前就拒绝请求,并返回 404 错误(在某些版本中可能返回 413 错误)。
注意事项
-
单位大小写:配置中的单位(MB、KB)不区分大小写,但建议使用大写以保持一致性。
-
max-request-size 必须大于等于 max-file-size:
max-request-size应该设置为大于或等于max-file-size,因为一个请求可能包含多个文件和其他表单数据。 -
临时文件清理:如果设置了
location,需要确保临时目录有足够的空间,并且定期清理临时文件。 -
Nginx 等反向代理配置:如果使用了 Nginx 等反向代理,还需要在 Nginx 配置中增加
client_max_body_size参数:
|
|
- Tomcat 配置:如果使用内嵌的 Tomcat,可能还需要配置
maxSwallowSize:
|
|
验证配置
配置完成后,可以通过以下方式验证:
- 使用 Postman 或 curl 测试上传不同大小的文件
- 查看应用日志,确认请求是否正常到达 Controller
- 检查返回的状态码,应该是 200(成功)或 400(业务错误),而不是 404