ServletException - 인터셉터

현시기얌·2021년 8월 15일

ServletException

목록 보기
5/7

LogInterceptor

@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 logId = UUID.randomUUID().toString();

        request.setAttribute(LOG_ID, logId);

        //@RequestMapping : HandlerMethod
        //정적 리소스 : ResourceHttpRequestHandler

        if (handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) handler; //호출할 컨트롤러 메서드의 모든 정보가 포함되어 있다.
        }

        log.info("Request [{}][{}][{}][{}]", logId, request.getDispatcherType(), requestURI, handler);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandler [{}]", modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        String requestURI = request.getRequestURI();
        String logId = (String) request.getAttribute("logId");

        log.info("Request [{}][{}][{}][{}]", logId, request.getDispatcherType(), requestURI, handler);

        if (ex != null) {
            log.error("afterCompletion error!!", ex);
        }


    }
}

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/**"); // 오류 페이지 경로 추가
    }
}

Filter에서는 filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ERROR);
를 이용하여 해당 요청이 발생했을 때만 필터가 적용 되도록 했었다. 또한 기본 값이 REQUEST이기 때문에 특별한 이유가 없는 한 별다른 설정없이 사용 가능하였다.

Interceptor에서는 Filter와 같이 DispaterType을 지정해 주는 기능은 없지만
.excludePathPatterns("/error-page/**");
예외 경로 설정 메소드를 이용하여 예외 발생 시 인터셉터가 2번 요청되는 것을 방지할 수 있다.

localhost:8080/error-ex 접속 시 예외발생

인터셉터 첫번째 요청

인터셉터에서 첫번째 요청이 왔지만 예외가 발생(afterCompletion error)하였다.
때문에 WAS에서 다시 인터셉터에게 요청을 하는게 일반적이지만 .excludePathPatterns("/error-page/**"); 메소드에 에러 페이지 경로를 설정해 놨기 때문에 더이상의 요청이 오지 않는다.

인터셉터 두번째 요청 없이 마무리

최종 정리

/hello 정상 요청

WAS (/hello, dispatchType=REQUEST) --> Filter --> Servlet --> Interceptor --> Controller --> View

/error-ex 오류 요청

필터는 DispatchType으로 중복 호출 제거 (dispatchType=REQUEST)
인터셉터는 예외 경로 정보로 중복 호출 제거 (excludePathPatterns("/error-page/**"));

  1. WAS (/error-ex, dispatchType=REQUEST) --> Filter --> Sevlet --> Interceptor --> Controller
  2. WAS (여기까지 전파) <-- Filter <-- Servlet <-- Interceptor <-- Controller (예외발생)
  3. WAS 오류 페이지 확인
  4. WAS (/error-page/500, dispatchType=ERROR) --> Filter(X) --> Servlet --> Interceptor(X) --> Controller (/error-page/500) -> View
profile
현시깁니다

0개의 댓글