오봉이와 함께하는 개발 블로그
스프링 MVC 2 - 서블릿 예외 처리 : 인터셉터 본문
728x90
서블릿 예외 처리 - 인터셉터
LogInterceptor - DispatcherType 로그 추가
@Slf4j
public class LogInterceptor implements HandlerInterceptor {
public static final String LOG_ID = "logId";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
String uuid = UUID.randomUUID().toString();
request.setAttribute(LOG_ID, uuid);
log.info("REQUEST [{}][{}][{}][{}]", uuid, request.getDispatcherType(), requestURI, handler);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("postHandle [{}]", modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
String requestURI = request.getRequestURI();
String logId = (String)request.getAttribute(LOG_ID);
log.info("RESPONSE [{}][{}][{}]", logId, request.getDispatcherType(), requestURI);
if (ex != null) {
log.error("afterCompletion error!!", ex);
}
}
}
오류를 발생시키면 postHandle
은 실행되지 않는다.
WebConfig
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "*.ico",
"/error", "/error-page/**"); // "/error", "/error-page/**"는 오류 페이지 경로
}
// ........
}
앞서 필터의 경우에는 필터를 등록할 때 어떤 DispatcherType
인 경우에 필터를 적용할 지 선택할 수 있었다.
하지만 인터셉터는 서블릿이 제공하는 기능이 아니라 스프링이 제공하는 기능이기 때문에 DispatcherType
과 무관하게 항상 호출된다.
대신에 인터셉터는 다음과 같이 요청 경로에 따라서 추가하거나 제외하기 쉽게 되어 있기 때문에, 이러한 설정을 사용해서 오류 페이지 경로를 excludePathPatterns
를 사용해서 빼주면 된다.
여기에서 /error-page/**
를 제거하면 error-page/500
같은 내부 호출의 경우에도 인터셉터가 호출된다.
"/error-page/**"
를 빼고 error-404
를 접속했을 때는 에러 코드를 보내기 때문에 에러가 발생하여 postHandle
이 호출되지 않는다.
하지만, 에러 처리에서 작성한 ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error-page/404");
가 실행될 때는 @GetMapping("/error-page/404")
을 통해 컨트롤러가 정상 호출되는 것이기 때문에 postHandle
이 호출된다.
전체 흐름 정리
/hello
정상 요청
WAS(/hello, dispatchType=REQUEST) -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러 -> View
/error-ex
오류 요청
- 필터는
DispatchType
으로 중복 호출 제거(dispatchType=REQUEST
) - 인터셉터는 경로 정보로 중복 호출 제거(
excludePathPatterns("/error-page/**")
)
1. WAS(/error-ex, dispatchType=REQUEST) -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러
2. WAS(여기까지 전파) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생)
3. WAS 오류 페이지 확인
4. WAS(/error-page/500, dispatchType=ERROR) -> 필터(x) -> 서블릿 -> 인터셉터(x) -> 컨트롤러(/error-page/500) -> View
출처 : 인프런 김영한 지식공유자님 강의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
728x90
'BE > Spring' 카테고리의 다른 글
스프링 MVC 2 - API 예외 처리 : 시작 (0) | 2022.08.30 |
---|---|
스프링 MVC 2 - 스프링 부트 : 오류 페이지 (0) | 2022.08.30 |
스프링 MVC 2 - 서블릿 예외 처리 : 필터 (0) | 2022.08.30 |
스프링 MVC 2 - 서블릿 예외 처리 오류 페이지 작동 원리 (0) | 2022.08.30 |
스프링 MVC 2 - 서블릿 예외 처리 오류 화면 제공 (0) | 2022.08.30 |
Comments