요청 -> WAS -> Filter -> DispatcherServlet ->
Interceptor1 -> Interceptor2
-> 컨트롤러
필터에서 제공하는 대부분의 기능을 지원하며, 필터보다 더 편리하고 다양한 기능을 제공한다.
필터와 마찬가지로 인터셉터에도 URL 패턴을 적용할 수 있는데, 필터보다 더 정밀하게 설정할 수 있다.
인터셉터에서 적절하지 않은 요청이라고 판단하면 거기에서 요청을 끝낼 수 있다.
인터셉터는 컨트롤러 호출 전 (preHandle)
, 호출 후 (postHandle)
, 요청 완료 이후 (afterCompletion)
와 같이 단계적으로 세분화 되어 있다.
또한, 서블릿 필터
의 경우 단순히 request와 response만 제공했지만, 인터셉터
는 어떤 컨트롤러 (handler)가 호출되는지 호출 정보도 받을 수 있다. 그리고 어떤 modelAndView 가 반환되는지 응답 정보도 받을 수 있다
preHandle
: 핸들러 어댑터(HandlerAdapter) 호출 전에 호출된다.
preHandle 의 return 값이 true 이면 다음으로 진행하고, false 인 경우 나머지 인터셉터는 물론이고, 핸들러 어댑터도 호출되지 않고 요청이 끝나버린다.
postHandle
: 핸들러 어댑터(HandlerAdapter) 호출 후에 호출된다.
afterCompletion
: view 렌더링 이후에 호출된다.
컨트롤러에서 예외가 발생할 경우,
preHandle
의 경우 컨트롤러 이전에 호출되므로 영향을 받지 않는다.
postHandle
은 호출되지 않는다
afterCompletion
은 항상 호출된다.
afterCompletion() 메서드
를 보면 파라미터로 Exception을 받는 것을 확인할 수 있는데, 이를 활용해 예외 로그를 출력할 수 있다.
인터셉터는 WebMvcConfigurer
가 제공하는 addInterceptors() 를 통해 등록할 수 있다.
registry.addInterceptor()
: 인터셉터를 등록order()
: 인터셉터의 호출 순서를 지정addPathPatterns()
: 인터셉터를 적용할 URL 패턴을 지정excludePathPatterns()
: 인터셉터에서 제외할 패턴을 지정인증의 경우 컨트롤러 호출 전에만 호출하면 되므로, preHandle()
만 구현했다.
세션 존재 여부를 확인하고, 없을 경우 로그인 화면으로 이동한다.
이때, 기존의 요청 URI를 함께 보내어 로그인 후 기존 요청 화면으로 이동할 수 있도록 했다.
필터의 경우
필터를 적용할 URI를 직접 작성하여 로직에 포함해야 했지만,
인터셉터는
등록 시 메서드로 편리하게 지정할 수 있기 때문에 로직이 더 깔끔한 것을 볼 수 있다.
자료 출처 : 김영한님의 Spring MVC 2편