Spring Boot文件上传超限后前端无响应的问题求助
问题描述
配置Spring文件上传大小限制后,上传超过5MB的图片时,@RestControllerAdvice已成功捕获MaxUploadSizeExceededException/SizeLimitExceededException,且响应对象构造正确,但浏览器无法收到响应,网络状态显示(failed)net::ERR_CONNECTION_RESET。其他异常的捕获逻辑均正常工作,仅文件上传超限场景出现此问题。
已配置参数
spring.servlet.multipart.max-file-size=5MB spring.servlet.multipart.max-request-size=5MB server.error.include-message: always server.tomcat.max-swallow-size: -1
控制器代码
@PutMapping("/profile-picture") public ResponseEntity<Response> saveProfilePicture(@RequestBody MultipartFile file) { ResponseData responseData = uploadService.uploadFile(file); HttpStatus status = responseData.getStatus(); String msg = responseData.getMessage(); Response response = Response.builder() .code("PROFILE_PICTURE") .status(status) .timestamp(LocalDateTime.now()) .messages(List.of(msg)) .build(); return ResponseEntity.status(status).body(response); }
异常处理类代码
@RestControllerAdvice public class RestExceptionHandler { @ExceptionHandler({IllegalArgumentException.class, PSQLException.class, ExpiredJwtException.class, MalformedJwtException.class, SignatureException.class, AccessDeniedException.class, MaxUploadSizeExceededException.class, SizeLimitExceededException.class}) private ResponseEntity<Object> handleExceptions(Exception exception) { HttpStatus status; List<String> errorList = new ArrayList<>(); System.out.println("Caught exception of type: " + exception.getClass().getName()); switch (exception.getClass().getName()) { case "org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException", "org.springframework.web.multipart.MaxUploadSizeExceededException" -> { status = HttpStatus.BAD_REQUEST; errorList.add("File should not be larger than 5 MB"); } case "org.springframework.security.access.AccessDeniedException" -> { status = HttpStatus.UNAUTHORIZED; errorList.add("Access Denied"); } // Other exceptions ... default -> { status = HttpStatus.INTERNAL_SERVER_ERROR; errorList.add("An unexpected error occurred."); System.out.println("Unhandled exception of type: " + exception.getClass().getName()); } } Response response = Response.builder() .code(status.name()) .status(status) .timestamp(LocalDateTime.now()) .messages(errorList) .build(); return ResponseEntity.status(status).body(response); } }
解决方案
该问题核心是Tomcat在处理超大文件上传异常时,即便配置了max-swallow-size=-1,仍可能强制断开连接导致响应无法送达浏览器,可通过以下步骤解决:
1. 调整Tomcat核心配置
在配置文件中补充以下参数,确保连接超时和表单提交大小与上传限制匹配:
server.tomcat.connection-timeout: 30000 # 设置为30秒,可按需调整 server.tomcat.max-http-form-post-size: 5MB # 与multipart单文件限制保持一致
2. 修改异常处理方法可见性
当前异常处理方法为private,Spring无法正确代理该方法,需改为public:
@ExceptionHandler(...) public ResponseEntity<Object> handleExceptions(Exception exception) { // 原有逻辑保持不变 }
3. 显式指定响应Content-Type
在异常处理的响应构建中,明确设置JSON类型的Content-Type,避免浏览器解析异常:
return ResponseEntity.status(status) .contentType(MediaType.APPLICATION_JSON) .body(response);
4. 切换为CommonsMultipartResolver(可选)
若使用Spring Boot 2.x及以上版本,默认的StandardServletMultipartResolver在异常处理上存在局限性,可改用CommonsMultipartResolver:
配置Bean
@Configuration public class MultipartConfig { @Bean public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setMaxUploadSize(5 * 1024 * 1024); // 总上传大小限制5MB resolver.setMaxUploadSizePerFile(5 * 1024 * 1024); // 单文件大小限制5MB resolver.setDefaultEncoding("UTF-8"); return resolver; } }
添加依赖
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.5</version> </dependency>
内容的提问来源于stack exchange,提问作者xRay
相关产品推荐
相关产品推荐

