HOWTO handle 404 exceptions globally using Spring MVC configured using Java based Annotations
[java] 스프링 부트 REST 서비스 예외 처리[리뷰나라]
Spring에서 아래와 같이 ControllerAdvice로 @ExceptionHandler를 사용해 Error들을 Handling 할 수 있는데,
@RestControllerAdvice는 @ResponseBody가 붙은 @ControllerAdvice
@RestControllerAdvice
public class ExceptionController {
@SuppressWarnings("unused")
private static final Logger LOG = Logger.getLogger(ExceptionController.class);
@Autowired
private ExceptionService exceptionService;
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
protected ResponseEntity<ErrorResponse> handleHttpRequestMethodNotSupportedException(
HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
exceptionService.errorLog(e, request);
return new ResponseEntity<>(
new ErrorResponse(HttpStatus.METHOD_NOT_ALLOWED.value(), "MethodNotSupported", e.getMessage()),
HttpStatus.METHOD_NOT_ALLOWED);
}
@ExceptionHandler(NoHandlerFoundException.class)
protected ResponseEntity<ErrorResponse> handleNoHandlerFoundException(NoHandlerFoundException e,
HttpServletRequest request) {
exceptionService.errorLog(e, request);
return new ResponseEntity<>(new ErrorResponse(HttpStatus.NOT_FOUND.value(), "Not Found", e.getMessage()),
HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
protected ResponseEntity<ErrorResponse> handleException(Exception e, HttpServletRequest request) {
exceptionService.errorLog(e, request);
return new ResponseEntity<>(new ErrorResponse(HttpStatus.BAD_REQUEST.value(), request.getSession().getId()),
HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(JwtException.class)
protected ResponseEntity<ErrorResponse> handleJwtException(JwtException e, HttpServletRequest request) {
exceptionService.errorLog(e, request);
return new ResponseEntity<>(new ErrorResponse(HttpStatus.UNAUTHORIZED.value(), "JwtException", e.getMessage()),
HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(AuthenticationException.class)
protected ResponseEntity<ErrorResponse> handleAuthenticationException(AuthenticationException e,
HttpServletRequest request) {
exceptionService.errorLog(e, request);
return new ResponseEntity<>(
new ErrorResponse(HttpStatus.UNAUTHORIZED.value(), "AuthenticationException", e.getMessage()),
HttpStatus.UNAUTHORIZED);
}
}
404 Error을 Handling하기 위해 NoHandlerFoundException을 @ExceptionHandler로 Handling 해보려 했지만 적용되지 않았다.
이를 해결하기 위해선 DispatcherServlet이 HandlerMapping에게 Request를 처리할 Handler를 찾도록 요청할 때,
Handler를 찾지 못할 경우 NoHandlerFoundException을 Throw 하게 해주어야 한다.
방법은 서버 환경에 따라 다른데, 자신의 서버 환경에 따라 아래 방법을 설정하자.
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/servlet-context.xml</param-value>
</init-param>
<init-param>
<param-name>throwExceptionIfNoHandlerFound</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
@ComponentScan()
@EnableAutoConfiguration
public class MyApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
DispatcherServlet dispatcherServlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
}
}
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
spring:
# error 404
mvc:
throw-exception-if-no-handler-found: true
dispatch-options-request: false
21-08-28 추가 위 방법 말고 아래 방법으로 성공했다는 의견 존재
spring:
web:
resources:
add-mappings: false
위 설정 이후에 정상적으로 NoHandlerFoundException이 Throw되어,
@ExceptionHandler(NoHandlerFoundException.class)에서 Handling 할 수 있었다.

오늘도 해결 완료 :) 🙆♀️
Spring Boot - *.yml 적용시
dispatch-options-request: false 는 안써도 되고
spring:
web:
resources:
add-mappings: false
를 적용해야 했습니다.