如何使用嵌入式 tomcat 在 Spring Boot 中增加文件大小上传限制
Posted
技术标签:
【中文标题】如何使用嵌入式 tomcat 在 Spring Boot 中增加文件大小上传限制【英文标题】:How to increase file size upload limit in spring boot using embedded tomcat 【发布时间】:2020-06-19 05:47:07 【问题描述】:我正在尝试使用我的 Spring Boot API 上传文件。当我使用小文件(小于 1 MB)时,该功能工作正常,但是当我上传大文件时,它给了我一个异常。我正在使用嵌入式 Tomcat 服务器。
“超出最大上传大小;嵌套异常是 java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: 字段文件超出了其最大允许大小 1048576 字节。”
我在我的文件中尝试了以下代码,但每次我都收到错误
1.应用程序.property
server.tomcat.max-swallow-size=100MB
server.tomcat.max-http-post-size=100MB
spring.servlet.multipart.enabled=true
spring.servlet.multipart.fileSizeThreshold=100MB
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
我也试过了
spring.servlet.multipart.maxFileSize=100MB
spring.servlet.multipart.maxRequestSize=100MB
2。爱人是我的文件上传代码
public RestDTO uploadFile(MultipartFile file, String subPath)
if (file.isEmpty())
return new RestFailure("Failed to store empty file");
try
String fileName = new Date().getTime() + "_" + file.getOriginalFilename();
String filePath = uploadPath + subPath + fileName;
if (Objects.equals(file.getOriginalFilename(), "blob"))
filePath += ".png";
fileName += ".png";
File uploadDir = new File(uploadPath + subPath);
if (!uploadDir.exists())
uploadDir.mkdirs();
FileOutputStream output = new FileOutputStream(filePath);
output.write(file.getBytes());
LOGGER.info("File path : " + filePath);
MediaInfoDTO mediaInfoDTO = getThumbnailFromVideo(subPath, fileName);
String convertedFileName = convertVideoToMP4(subPath, fileName);
System.out.println("---------------->" + convertedFileName);
return new RestData<>(new MediaDetailDTO(mediaInfoDTO.getMediaPath(), convertedFileName,
mediaInfoDTO.getMediaType(), mediaInfoDTO.getMediaCodec(), mediaInfoDTO.getWidth(),
mediaInfoDTO.getHeight(), mediaInfoDTO.getDuration()));
catch (IOException e)
LOGGER.info("Can't upload file: " + e.getMessage());
return new RestFailure("Failed to store empty file");
但每次我都遇到同样的异常。
【问题讨论】:
你使用的是哪个版本的 Spring Boot 我使用的是spring boot 2.1.7spring.servlet.multipart.max-file-size
和 spring.servlet.multipart.max-request-size
仅适用于 Spring Boot 2.1.7。尝试将它们都设置为 -1(基本上无限制)
我使用了 spring.servlet.multipart.max-file-size=-1 和 spring.servlet.multipart.max-request-size=-1。还是不行
用正确的字节大小更新答案
【参考方案1】:
除了评论,我还可以建议为 Factory MultipartConfigurationElement
创建一个 @Bean
如果您有来自 TomCat 方面的任何限制,这基本上应该覆盖其他限制。
@Bean
public MultipartConfigElement multipartConfigElement()
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize(DataSize.ofBytes(100000000L));
factory.setMaxRequestSize(DataSize.ofBytes(100000000L));
return factory.createMultipartConfig();
这里DataSize
的类型是org.springframework.util.unit.DataSize
参考https://github.com/spring-projects/spring-boot/issues/11284
我怀疑另一个问题可能来自 TomCat maxSwallowSize
如果上述方法不起作用,请参阅 Baeldung 的第 5 点。
https://www.baeldung.com/spring-maxuploadsizeexceeded
【讨论】:
没有必要这样做。 Spring Boot 将使用spring.servlet.multipart.*
属性自动配置MultipartConfigElement
。【参考方案2】:
在查看了许多示例并进行了多次测试但没有结果之后。我已经设法通过以下配置解决了这个问题:
在 pom 中添加以下依赖项:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
从 yml 中删除:
sprint:
servlet:
multipart:
enabled: true
file-size-threshold: 2KB
max-file-size: 10MB
max-request-size: 10MB
添加到 yml:
server:
tomcat:
max-swallow-size: -1
max-http-form-post-size: -1
最后但同样重要的是:
@Bean
public MultipartResolver multipartResolver()
CommonsMultipartResolver resolver
= new CommonsMultipartResolver();
resolver.setDefaultEncoding(StandardCharsets.UTF_8.displayName());
resolver.setMaxUploadSize(52428800L); //50MB
resolver.setMaxUploadSizePerFile(52428800L); //50MB
return resolver;
@ExceptionHandler(MaxUploadSizeExceededException.class)
public ResponseEntity<Object> handleFileUploadError(MaxUploadSizeExceededException ex)
return ResponseEntity.status(EXPECTATION_FAILED).body(
CustomResponse.builder()
.status(Status.ERROR)
.message(ex.getMessage())
.build());
// Where CustomResponse class is in my case:
/**
* The UploadResponse class
* <p>
* Contain the response body
*/
@Getter
@Builder(toBuilder = true)
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CustomResponse
/**
* The status
*/
private final Status status;
/**
* The message
*/
private final String message;
/**
* The errors
*/
private final Set<String> errors;
【讨论】:
自定义异常处理程序很好,否则你会得到一个丑陋的500 Internal Server
错误,这是由 Sprint 的默认异常处理程序提供的。但是,要增加文件大小限制,我所要做的就是将spring.servlet.multipart.max-file-size=10485760
添加到我的application.properties
。无需创建自定义 MultipartResolver
bean。以上是关于如何使用嵌入式 tomcat 在 Spring Boot 中增加文件大小上传限制的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spring Boot 嵌入式 tomcat 设置会话超时
如何使用嵌入式 Tomcat 容器在 Spring Boot 中创建 JNDI 上下文
如何使用 Spring Boot 和嵌入式 Tomcat 配置此属性?
如何在 Spring Boot 中关闭嵌入式 Tomcat?