我对 Spring 的控制器异常处理有疑问。我有一个带有
@RestControllerAdvice
注释的课程,其中有几个 @ExceptionHandler
,如下所示:
@ExceptionHandler(HttpRequestMethodNotSupportedException::class)
fun methodNotSupportedException(
exception: HttpRequestMethodNotSupportedException,
request: HttpServletRequest
): ResponseEntity<ApiError> {
logger().error("Method not supported: {}", exception.message)
val methodNotAllowed = HttpStatus.METHOD_NOT_ALLOWED
val apiError = logAndBuildApiError(request, methodNotAllowed, exception)
return ResponseEntity(apiError, methodNotAllowed)
}
而且它们工作得很好。在这种情况下,当我尝试使用未实现的 HTTP 方法(如 POST)时:
{
"requestUri": "/api/v1/items",
"status": 405,
"statusText": "Method Not Allowed",
"createdAt": "2023-01-12T16:50:36.55422+02:00",
"errorMessage": "Request method 'POST' not supported"
}
我想要实现的是处理有人试图到达不存在的端点的情况,即正确的端点是
GET http://localhost:8080/api/v1/items
。
但是当我尝试到达
http://localhost:8080/api/v1/itemss
(这当然是不存在的)时,我收到了常规的 Spring Whitelabel 错误页面,但我希望收到像前一个示例中那样的 JSON:
{
"requestUri": "/api/v1/itemss",
"status": 404,
"statusText": "Not Found",
"createdAt": "2023-01-12T16:52:06.932108+02:00",
"errorMessage": "Some error message"
}
如何实现
@ExceptionHandler
以便它可以处理与不存在资源相关的异常?
spring.mvc.throw-exception-if-no-handler-found
与
spring.mvc.static-path-pattern
。 默认情况下,静态路径模式为 /**,其中包括您看到的白标签错误页面。
参见https://github.com/spring-projects/spring-boot/pull/31660 和https://gitter.im/spring-projects/spring-boot?at=62ba1378568c2c30d30790af 和https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#web.servlet.spring-mvc.static-content
选项一是在配置中设置这两个属性。
spring:
mvc:
throw-exception-if-no-handler-found: true
static-path-pattern: /static
选项 2 是将
@EnableWebMvc
添加到您的 Spring Boot 应用程序中,并将 spring.mvc.throw-exception-if-no-handler-found
属性设置为 true。 通过添加 EnableWebMvc
,您将获得 WebMvcConfigurationSupport
bean,这将导致 Spring 不初始化 WebMvcAutoConfiguration
,从而不设置静态路径模式。
spring.mvc.throwExceptionIfNoHandlerFound=true
现已弃用
您可以通过处理
NoResourceFoundException.class
异常 来处理 404 错误
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ExceptionHandler(value = NoResourceFoundException.class)
public ResponseEntity<Object> handleNotfound(){
ResponseBean response = new ResponseBean();
response.setResponseCode(ResponseConstants.ResponseCodes.ERROR_URL.getCode());
response.setMessage(ResponseConstants.ResponseCodes.ERROR_URL.getMessage());
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
}
ResponseBean 是我的自定义类