davioooh
davioooh

Reputation: 24666

Spring MVC: how to intercept 404 before returning error page/response?

In my Spring Boot 2.2.x web application I need to intercept 404 errors so I can execute some custom logic before the error page is rendered or the json with error info is returned.

What's the correct way to achieve this?

At the moment I'm trying with a @ControllerAdvice class, but I don't know which exception to handle with the @ExceptionHandler method (if any is thrown)...

NOTE: I have already tried to intercept NoHandlerFoundException, but this doesn't seem to work... (the handler is not triggered).

@ControllerAdvice
public class ErrorHandler {
    @ExceptionHandler(NoHandlerFoundException.class)
    public void handleException() {
        System.out.println("It's a 404!");
    }
}

I also enabled this in my application.properties:

spring.mvc.throw-exception-if-no-handler-found=true

Any other suggestion?

Upvotes: 2

Views: 2697

Answers (3)

davioooh
davioooh

Reputation: 24666

I finally found the solution (or part of it) in this question: Custom exception handler for NoHandlerFoundException is not working without @EnableWebMvc

By default Spring doesn't throw an exception for 404 errors. You need to enable this property in application.properties (or yaml):

spring.mvc.throw-exception-if-no-handler-found=true

But you also need to set this property:

spring.mvc.static-path-pattern: /static

This restriction prevents Spring to search for static contents matching the missing path/handler.

Now you can intercept a NoHandlerFoundException as usual with @ExceptionHandler.

NOTE Before setting the spring.mvc.static-path-pattern property I tried to add @EnableWebMvc to a configuration class in my project: this way the NoHandlerFoundException was thrown but I obviously lost all the Spring Boot autoconfigurations.

Upvotes: 2

shazin
shazin

Reputation: 21883

In the same class you use @ControllerAdvice implement ErrorController.

@ControllerAdvice
public class ControllerAdvice implements ErrorController {

    @RequestMapping("/error")
    public ResponseEntity<Map> handleError(HttpServletResponse response) {
        Map errorMapJson = new HashMap();

        if(response.getStatus() == HttpStatus.NOT_FOUND.value()) {
            errorMapJson.put("type", "404 Error");
        }

        return new ResponseEntity<Map>(errorMapJson, HttpStatus.NOT_FOUND);
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }
}

Upvotes: 0

Prashant
Prashant

Reputation: 5383

Use NoHandlerFoundException. This maps to 404 in spring boot.

Upvotes: 1

Related Questions