Tomcat Servlet 3.0 多部分文件上传临时文件夹中的名称冲突
Tomcat Servlet 3.0 multipart file upload name clash in temp folder
似乎 Tomcat 没有处理两个不同用户并行上传同一个多部分文件。
测试
- 两个 sessions/users A 和 B
- 两个人同时上传了一个 20MB 的文件同名
foo.pdf
- 默认配置的Servlet 3.0 Request将这两个文件存放在tmp文件夹中
- 两个线程都尝试将
foo.pdf
写入 tmp 文件夹
结果
- 上传的文档已损坏(两个流写入)
- 较慢的请求将失败并显示
FileNotFoundException
,因为 tmp 文件已被较快请求的清理任务删除。
有没有办法避免这种情况 - 除了将 fileSizeThreshold
设置为高于 maxFileSize
以便它永远不会首先写入磁盘。
旁注:这是一个 Spring Boot 2.1 应用程序,但这无关紧要,因为它默认使用此 Servlet 3.0 实现。
我有一个答案,但不是很满意。我们没有弄清楚如何使用 Tomcat 的 Servlet 3.0 实现来实现这一点。但是,一旦我们切换到 Apache commons-fileupload,一切都很好。
所以,对于 Spring (Boot) applications 你会
- 设置
spring.servlet.multipart.enabled: false
- 配置一个
CommonsMultipartResolver
类型的 bean,名称为 multipartResolver
- 添加
commons-fileupload
依赖项
似乎 Tomcat 没有处理两个不同用户并行上传同一个多部分文件。
测试
- 两个 sessions/users A 和 B
- 两个人同时上传了一个 20MB 的文件同名
foo.pdf
- 默认配置的Servlet 3.0 Request将这两个文件存放在tmp文件夹中
- 两个线程都尝试将
foo.pdf
写入 tmp 文件夹
结果
- 上传的文档已损坏(两个流写入)
- 较慢的请求将失败并显示
FileNotFoundException
,因为 tmp 文件已被较快请求的清理任务删除。
有没有办法避免这种情况 - 除了将 fileSizeThreshold
设置为高于 maxFileSize
以便它永远不会首先写入磁盘。
旁注:这是一个 Spring Boot 2.1 应用程序,但这无关紧要,因为它默认使用此 Servlet 3.0 实现。
我有一个答案,但不是很满意。我们没有弄清楚如何使用 Tomcat 的 Servlet 3.0 实现来实现这一点。但是,一旦我们切换到 Apache commons-fileupload,一切都很好。
所以,对于 Spring (Boot) applications 你会
- 设置
spring.servlet.multipart.enabled: false
- 配置一个
CommonsMultipartResolver
类型的 bean,名称为multipartResolver
- 添加
commons-fileupload
依赖项