diff --git a/common-web/src/main/java/com/baiyue/common/web/GlobalExceptionHandler.java b/common-web/src/main/java/com/baiyue/common/web/GlobalExceptionHandler.java index 8df2058e0..da926f706 100644 --- a/common-web/src/main/java/com/baiyue/common/web/GlobalExceptionHandler.java +++ b/common-web/src/main/java/com/baiyue/common/web/GlobalExceptionHandler.java @@ -24,6 +24,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.resource.NoResourceFoundException; import org.springframework.web.server.ResponseStatusException; +import org.springframework.web.multipart.MaxUploadSizeExceededException; import java.util.LinkedHashMap; import java.util.Map; @@ -105,6 +106,16 @@ public class GlobalExceptionHandler { return failure(ResultCode.CONFLICT, "资源正在处理中,请稍后重试", request); } + @ExceptionHandler(MaxUploadSizeExceededException.class) + public ResponseEntity> handleMaxUploadSize( + MaxUploadSizeExceededException exception, HttpServletRequest request) { + long maxBytes = exception.getMaxUploadSize(); + String message = maxBytes > 0 + ? "上传文件不能超过" + Math.max(1, (maxBytes + 1024 * 1024 - 1) / (1024 * 1024)) + "MB" + : "上传文件超过服务允许大小"; + return failure(ResultCode.BAD_REQUEST, message, request); + } + @ExceptionHandler(Exception.class) public ResponseEntity> handleUnexpected(Exception exception, HttpServletRequest request) { log.error("Unhandled request failure requestId={} traceId={}", diff --git a/common-web/src/test/java/com/baiyue/common/web/GlobalExceptionHandlerTest.java b/common-web/src/test/java/com/baiyue/common/web/GlobalExceptionHandlerTest.java index c98f8c305..d70a952ba 100644 --- a/common-web/src/test/java/com/baiyue/common/web/GlobalExceptionHandlerTest.java +++ b/common-web/src/test/java/com/baiyue/common/web/GlobalExceptionHandlerTest.java @@ -17,6 +17,7 @@ import org.springframework.test.util.ReflectionTestUtils; import org.springframework.http.HttpStatus; import org.springframework.web.server.ResponseStatusException; import org.springframework.dao.CannotAcquireLockException; +import org.springframework.web.multipart.MaxUploadSizeExceededException; import java.lang.reflect.Method; @@ -129,6 +130,20 @@ class GlobalExceptionHandlerTest { assertThat(response.getBody().requestId()).isEqualTo("lock-timeout"); } + @Test + void oversizedMultipartReturnsClearBadRequestInsteadOfInternalError() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setAttribute(CorrelationContext.REQUEST_ID, "oversized-photo"); + + var response = handler.handleMaxUploadSize( + new MaxUploadSizeExceededException(10L * 1024 * 1024), request); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThat(response.getBody().code()).isEqualTo(ResultCode.BAD_REQUEST.code()); + assertThat(response.getBody().message()).isEqualTo("上传文件不能超过10MB"); + assertThat(response.getBody().requestId()).isEqualTo("oversized-photo"); + } + private void paging(long page) { } } diff --git a/config/nacos/overseas/lastleg-service.yml b/config/nacos/overseas/lastleg-service.yml index c4d919be3..3c63429f0 100644 --- a/config/nacos/overseas/lastleg-service.yml +++ b/config/nacos/overseas/lastleg-service.yml @@ -1,4 +1,8 @@ spring: + servlet: + multipart: + max-file-size: ${LASTLEG_MULTIPART_MAX_FILE_SIZE:10MB} + max-request-size: ${LASTLEG_MULTIPART_MAX_REQUEST_SIZE:11MB} datasource: url: ${LASTLEG_DB_URL} username: ${LASTLEG_DB_USERNAME} diff --git a/lastleg-service/src/main/resources/application.yml b/lastleg-service/src/main/resources/application.yml index 9a76d798a..b44c1dfed 100644 --- a/lastleg-service/src/main/resources/application.yml +++ b/lastleg-service/src/main/resources/application.yml @@ -1,6 +1,10 @@ server: port: ${LASTLEG_PORT:9303} spring: + servlet: + multipart: + max-file-size: ${LASTLEG_MULTIPART_MAX_FILE_SIZE:10MB} + max-request-size: ${LASTLEG_MULTIPART_MAX_REQUEST_SIZE:11MB} sql: init: mode: always diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/ReceivingPhotoUploadConfigurationContractTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/ReceivingPhotoUploadConfigurationContractTest.java new file mode 100644 index 000000000..137aaf146 --- /dev/null +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/ReceivingPhotoUploadConfigurationContractTest.java @@ -0,0 +1,29 @@ +package com.baiyue.lastleg.inboundplan.pda; + +import org.junit.jupiter.api.Test; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.assertj.core.api.Assertions.assertThat; + +class ReceivingPhotoUploadConfigurationContractTest { + @Test + void lastlegAcceptsTheSameTenMegabyteLimitAsFileService() throws Exception { + String application = read("lastleg-service/src/main/resources/application.yml"); + String overseas = read("config/nacos/overseas/lastleg-service.yml"); + + for (String configuration : new String[]{application, overseas}) { + assertThat(configuration).contains( + "max-file-size: ${LASTLEG_MULTIPART_MAX_FILE_SIZE:10MB}", + "max-request-size: ${LASTLEG_MULTIPART_MAX_REQUEST_SIZE:11MB}"); + } + } + + private static String read(String relative) throws Exception { + Path path = Path.of(relative); + if (!Files.exists(path)) path = Path.of("..").resolve(relative); + return Files.readString(path, StandardCharsets.UTF_8); + } +}