In a similar way as gaetan224 suggested, you can add a controller using @ControllerAdvice to handle exceptions in a custom way:
@ControllerAdvice
@RequestMapping(produces = "application/json")
@ResponseBody
public class RestControllerAdvice {
@Autowired
Environment env;
@ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<?> unhandledPath(final NoHandlerFoundException e) {
//This is for 405 METHOD NOT ALLOWED
//Here you may want to return a ResponseEntity with a custom POJO as body.
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ResponseEntity<?> methodNotAllowed(final HttpRequestMethodNotSupportedException e) {
//This is for 404 NOT FOUND
//Here you may want to return a ResponseEntity with a custom POJO as body.
}
}
Things get a little bit different when handling 403 UNAUTHORIZED in Spring Security. You must write a @Component that implements the AccessDeniedHandler interface. Something like this:
@Component
public class AccessEntryPoint implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest req,
HttpServletResponse res,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
ObjectMapper mapper = new ObjectMapper();
res.setContentType("application/json;charset=UTF-8");
res.setStatus(403);
res.getWriter().write( /*Your custom object may go here*/ );
}
}
But this is not enough, you must also set your custom AccessDeniedHandler implementation in your WebSecurityConfigureAdapter implementation using:
@Autowired
AccessEntryPoint accessDeniedHandler;
And appending the following to your configuration method call chain:
.exceptionHandling().accessDeniedHandler(accessDeniedHandler).and()
EDIT: I forgot to add that in order for the 404 custom handler to work, you must add this two lines in your application.properties file:
spring.resources.add-mappings=false
spring.mvc.throw-exception-if-no-handler-found=true