상황 : 장바구니, 멤버십 전용 메뉴 등을 이용할 때, 로그인을 해야 접근할 수 있는 경우들이 있다. 이와 같이, 로그인이 지속적으로 필요한 기능을 구현할 때, 해당 로직에 로그인 기능을 반복해서 추가해야만 한다.
이렇게 공통적인 처리를 대신 해주는 객체를 구현해준다면, 반복적인 코드 작성 뿐만 아니라, 재사용성과 유연한 결합까지 모두 챙길 수 있다.
서블릿 필터와 스프링 인터셉터는 HttpServletRequest, HttpServletResponse를 제공해주기 때문에, url 정보나 http header를 직접 조작할 수 있다.
서블릿 필터

Servlet API 2.3부터 등장해, Dispatcher Servlet의 요청이 전달되기 전 후, 실행을 낚아 채어 부가작업을 처리하는 객체
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain){
HttpServletRequest servletRequest = (HttpServletRequest) reqeust;
try{
validateToken(servletRequest);// 인증 로직
chain.doFilter(request,response);
}catch(Exception e){
HttpServletResponse servletResponse = (HttpServletResponse) response;
servletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
}
}
Filter를 적용하는 방법
1) @Component 애노테이션 적용
2)@WebFilter & @ServletComponentScan 애노테이션 적용
3)FilterRegistrationBean 객체로 메서드 호출하기
스프링 인터셉터

Handler 조회 → 적절한 HandlerAdapter 가져옴 → preHandle → HandlerAdapter를 통해 Handler 실행 → postHandle → view 처리 → afterCompletion
디스패처 서블릿이 컨트롤러 호출 전/후로 실행을 낚아채어 부가적인 작업을 수행하도록 하는 것
인터셉터 등록 방법
1) WebMvcConfigurer 인터페이스를 구현한 클래스 내부에서 addInterceptor 메서드를 오버라이딩
2) addPathPatterns(”/***”)로 모든 URI 요청에 대해서 인터셉터 적용
3)excludePathPatterns(”/***”)로 인터셉터를 적용하지 않을 URI를 작성
Interceptor 동작 방식
1) DispatcherServlet.doService 메서드 호출
2) doDispatch 메서드 호출 →getHandler로 알맞은 handler를 가져옴(핸들러 조회)
3)getHandlerAdapter → handler에 맞는 handlerAdapter를 찾아온다.
4)preHandle 메서드를 실행하기 위해, HandlerExecutionChain의 applyHandler 메서드 호출
5) 직접 구현한 Interceptor의 preHandle 메서드가 실행
6) HandlerAdapter를 통해 Handler가 실행
7) 비즈니스 로직이 모두 실행된 후, postHandle을 실행할 수 있는 applyPostHandle 메서드가 호출 된 후 반복문을 돈다.
8) preHandle과는 역순으로 실행
9) 직접 구현한 Interceptor의 postHandle이 실행
10) DispatcherServlet의 processDispatchResult 메서드가 호출
11) render 메서드 호출 → view 관련 로직 처리
12) afterCompletion 메서드 실행
13) 직접 구현한 Interceptor의 afterCompletion이 실행
필터 vs 인터셉터
| 필터 | 인터셉터 |
|---|---|
| 자바 표준 스펙 | 스프링이 제공하는 기술 |
| 필터 실행을 위해 개발자가 명시적으로 작성해야 한다. | 다음 인터셉터를 실행하기 위해 개발자가 신경써야 할 부분이 없다 |
| ServletRequest, ServletResponse를 필터 체이닝 중간에 새로운 객체로 바꿀 수 있다. | ServletRequest, ServletResponse를 인터셉터 체이닝 중간에 새로운 객체로 바꿀 수 없다. |
| 필터 예외 발생 시, @ControllerAdvice에서 처리하지 못한다. | 인터셉터 예외 발생 시, @ControllerAdvice에서 처리할 수 있다. |