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
를 적용해야 했습니다.