简体   繁体   中英

How to handle 404 exceptions using @ControllerAdvice and @ExceptionHandler?

I have a problem with Spring's exception handling for controllers. I have a class annotated with @RestControllerAdvice with a couple of @ExceptionHandler 's, like this:

@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)
}

and they work perfectly fine. In this case, when I'm trying to use an non-implemented HTTP method like 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"
}

What I would like to achieve is to handle situations when someone is trying to reach an non-existing endpoint, ie the correct one is GET http://localhost:8080/api/v1/items .

But when I'm trying to reach http://localhost:8080/api/v1/itemss , which is of course nonexistent, I recieve a regular Spring whitelabel error page, but I would like to receive a JSON like in the former example:

{
    "requestUri": "/api/v1/itemss",
    "status": 404,
    "statusText": "Not Found",
    "createdAt": "2023-01-12T16:52:06.932108+02:00",
    "errorMessage": "Some error message"
}

How do I implement a @ExceptionHandler so it could handle exceptions related to non-existing resources?

spring.mvc.throw-exception-if-no-handler-found works in conjunction with spring.mvc.static-path-pattern . By default, the static path pattern is /**, which includes the whitelabel error pages that you're seeing.

See https://github.com/spring-projects/spring-boot/pull/31660 and https://gitter.im/spring-projects/spring-boot?at=62ba1378568c2c30d30790af and https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#web.servlet.spring-mvc.static-content

Option one is to set these two properties in your configuration.

spring:
  mvc:
    throw-exception-if-no-handler-found: true
    static-path-pattern: /static

Option 2 is to add @EnableWebMvc to your spring boot application, and set the spring.mvc.throw-exception-if-no-handler-found property to true. By adding EnableWebMvc you'll be getting the WebMvcConfigurationSupport bean, which will cause Spring not to initialize the WebMvcAutoConfiguration and thereby not set the static-path-pattern.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM