Java:如何处理Tomcat文件大小超过异常

6

我正在开发一个Spring Boot项目,想要处理最大文件大小超过异常(我只想上传小于10MB的文件,如果有人试图上传大于10MB的文件,它应该返回一条消息而不是异常)。在互联网上搜索后,我尝试了所有可能的解决方案,但都没有起作用。

有人可以告诉我怎么做吗?

FileUploadController.class

@ControllerAdvice
@Controller
public class FileUploadController extends ResponseEntityExceptionHandler{
@ExceptionHandler(MaxUploadSizeExceededException.class)
    @RequestMapping(method = RequestMethod.POST, value = "/uploadChildPhoto/{childId}", produces = "application/json")
    public @ResponseBody ResponseEntity<?> uploadChildPhoto(Authentication authentication,
            @PathVariable("childId") Long childId, @RequestParam("file") MultipartFile file,MaxUploadSizeExceededException exc) {
        try {
            if (!file.isEmpty()) {
                ChildPhoto createdPhoto = childService.createChildPhoto(file, childId);
                return ResponseEntity.ok(createdPhoto);
            } else {
                throw new RuntimeException(
                        "You failed to upload " + file.getOriginalFilename() + " because the file was empty");
            }
        } catch (MultipartException ex) {
            ex.printStackTrace();
            return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).body("File size error");
        }
    }
}

异常

org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (14816520) exceeds the configured maximum (10485760)
    at org.apache.tomcat.util.http.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:805) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:256) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:280) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.connector.Request.parseParts(Request.java:2864) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.connector.Request.parseParameters(Request.java:3211) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.connector.Request.getParameter(Request.java:1137) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:381) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:75) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.23.jar:8.5.23]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.23.jar:8.5.23]

最大文件大小

spring.http.multipart.max-file-size=10MB
spring.http.multipart.max-request-size=10MB

文件大小看起来约为14 MB,你应该尝试将配置值提高到更高的值并重试一下,怎么样? - CGS
@Chids 是的!文件大小为14MB,我想限制文件大小为10MB。如果有人上传大于10MB的文件,则显示消息而不是异常。 - SFAH
这些异常在你的代码之前被抛出 - 它们在Tomcat中。 - Scary Wombat
1
@ScaryWombat 那我该怎么处理这个问题呢? - SFAH
3个回答

3

由于Tomcat抛出了异常,您无法处理它。因此,您需要告诉Tomcat允许上传所有大小的文件,并在控制器级别处理大小。

设置以下多部分属性 multipart: max-file-size:-1 max-request-size:-1

设置Tomcat 8(maxSwallowSize =“-1”) 在控制器上,添加逻辑以检查大小

if(fileAttachment.getSize() > 10485760 ) { throw new MaxUploadSizeExceededException(fileAttachment.getSize()); }

1
一个有用的链接 https://www.mkyong.com/spring/spring-file-upload-and-connection-reset-issue/ - Scary Wombat
你完全可以在自己的代码中处理这个问题:使用一个“过滤器”并捕获异常,然后按照你想要的方式进行响应。 - Christopher Schultz

0
由于这个 - spring.http.multipart.max-file-size=10MB spring.http.multipart.max-request-size=10MB 控制不会传递到控制器。Tomcat只会抛出异常。 如果你想返回消息,那么从属性文件中删除这些行,并在你的控制器中添加一个检查,例如:
 if (file.getSize() > 10000000){
  throw new RuntimeException("File size error");
}

0
从tomcat抛出的异常,它无法访问控制器。
所以,我们有很多可能的处理方式(:
1. 添加以下应用程序属性并进行大小限制逻辑。

spring.http.multipart.max-file-size=-1

spring.http.multipart.max-request-size=-1

-1 表示它可以允许无限大小。但这只适用于开发,不适用于生产级应用程序。
在逻辑类内部,您可以定义自己的大小限制逻辑。您可以获取文件的大小,并根据需要抛出异常。
    if(fileAttachment.getSize() > 10485760 ) 
  {
//error logic throwing exception or return the error response.
 }

注意:10485760字节的值等于10MB。
2. 在一个generalException处理程序类中提到一个multipart异常。
@ControllerAdvice
public class GlobalExceptionHandler {
        @ExceptionHandler(MultipartException.class)
public ResponseEntity<String>fileExced(MultipartException ex){
    return ResponseEntity.ok("File limit exceeded..!");
}

这个问题中提到的sizeExceedException隐式地调用了multipart exception。所以每当文件限制超过上述错误消息时,就会抛出该错误消息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接