NoHandlerFoundException ControllerAdvice에서 제어하기
대부분 ControllerAdvice에서 에러를 제어하지만 간혹 dispatcherServlet에서 출력하는 에러들이 있습니다.
이에러는 Interceptor에서 로그인하지 않은 사용자를 체크하기 위해 throw된 Exception에 의해 발생하지만 항상 dispatcherServlet에서 에러를 출력하지는 않습니다.
@Component
class AuthInterceptor: AsyncHandlerInterceptor {
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
/**
* - 로그인 체크
*/
if (account.isNotLogin) {
throw AuthorizationException()
}
return true
}
}
그렇다면 언제 dispatcherServlet와 ControllerAdvice에러가 구분될까요?
dispatcherServlet 의 에러는 Handler (endpoint)가 존재하지 않을때 발생하게 됩니다.
기본적으로 DispatcherServlet → preHandler(HandlerInterceprot) → Controller → postHandler(HandlerInterceprot) → DispatcherServlet → afterCompletion → 응답으로 동작하기 때문에 afterCompletion이전에 발생한 예외는 모두 DispatcherServlet으로 반환되어 ControllerAdvice에서 핸들링 할 수 있습니다.
하지만 핸들러가 존재하지 않으면 preHandler에서 예외를 발생시키고 Default Error Page인 /error로 재호출되는 패턴입니다.
미정의된 Handler 요청 또한 ControllerAdvice에서 제어하고 싶다면 다음과 같이 처리할 수 있습니다.
spring:
mvc.throw-exception-if-no-handler-found: true
web.resources.add-mappings: false
+
ControllerAdvice NoHandlerFoundException 정의
spring.mvc.throw-exception-if-no-handler-found: true 이 옵션만 설정한 경우 매핑된 핸들러가 없다고 착각할 수 있지만 기본적으로 ResourceHttpRequestHandler가 추가되기 때문에 spring.web.resources.add-mappings: false도 비활성화 해야합니다.
만약 사용할 Resource가 있다면 직접 resourceHandler을 추가하면 됩니다.
'DEVELOPE' 카테고리의 다른 글
Interface-based Projection에서 ZonedDateTime Converter 사용 (0) | 2023.02.08 |
---|
댓글