Server/Spring

Spring - 필터(Filter)와 인터셉터(Interceptor)의 차이

JaeHoney 2022. 4. 27. 21:23

필터(Filter) / 인터셉터(Interceptor) / AOP

스프링에서 요청이 구현한 Controller Layer로 들어오기 전에 처리해야 하는 작업이 있다. 대표적으로 인증 인가, XSS 방어, 데이터 압축, 인코딩 등이 있다.

 

이러한 작업들은 공통 관심사로 보고 분리하는 것이 것이 효율적이다. 이때 사용할 수 있는 것이 필터(Filter)와 인터셉터(Interceptor), Spring AOP이다.

 

문제는 해당 기술들이 어떠한 장단점이 있으며, 어떤 경우에 적합한 지 또는 어떤 경우에 부적절한 지 등이 정리가 잘 되어있지 않다.

 

해당 포스팅에서는 그러한 기준을 정리한다.

 

필터(Filter)

필터(Filter)는 스프링이 지원하는 기능이 아닌, J2EE 표준 스펙에 있는 기능으로 가장 앞단에 존재하는 프론트 컨트롤러인 디스패처 서블릿(Dispatcher Servlet)에 요청이 전/후에 부가적인 작업을 처리할 수 있는 기능을 제공한다.

 

필터는 주로 @WebFilter 애노테이션을 사용해서 등록할 수 있고, 스프링 시큐리티(Spring Security)에서는 필터를 조립해서 계층적으로 구현할 수도 있다.

 

[ 필터(Filter)의 메소드 ]

필터는 javax.sevlet의 Filter 인터페이스를 구현해야 하며 3가지 메서드를 가지고 있다.

  • init Method
    • 필터 객체를 초기화하고 서비스에 추가하기 위한 메소드이다.
  • doFilter Method
    • 처리를 구현해서 동작한 후 받은 FilterChain 파라미터를 사용해서 다음 대상으로 요청을 넘겨준다.
  • destory Method
    • 필터를 제거하고 자원을 반환하기 위한 메소드이다.
public interface Filter {

    public default void init(FilterConfig filterConfig) throws ServletException {}
    
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;
            
    public default void destroy() {}

}

인터셉터(Interceptor)

인터셉터(Interceptor)는 스프링(Spring)이 제공하는 기술로써 디스패처 서블릿(Dispatcher Servlet)이 컨트롤러를 호출하기 전과 후에 요청을 가로채서 응답을 참조하거나 가공할 수 있게 도와준다.

 

인터셉터는 필터와 다르게 스프링 컨텍스트 내부에서 동작한다.

 

디스패처 서블릿(Dispatcher servlet)은 내부적으로 핸들러 매핑을 통해 적절한 컨트롤러를 찾도록 요청하는데 그 결과로 실행 체인(HandlerExecutionChain)을 반환한다.

 

실행 체인은 스프링 컨테이너에 인터셉터가 등록되어 있다면 인터셉터들을 순차적으로 거친 후에 컨트롤러를 실행하도록 한다.

 

 

[ 인터셉터(Interceptor)의 메소드 ]

인터셉터는 org.springframwork.web.servlet의 HandlerInterceptor 인터페이스를 구현해야 하고 3가지 메소드가 있다.

  • preHandle Method
    • 컨트롤러가 호출되기 전에 실행된다.
    • 요청 데이터 전처리, 가공 등에 사용한다.
  • postHandle Method
    • 컨트롤러가 호출된 후에 실행된다.
    • 후처리 작업이 있을 때 사용한다.
  • afterCompletion Method
    • 뷰 생성을 포함한 모든 작업이 완료된 후에 실행된다.
public interface HandlerInterceptor 

    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
	throws Exception {
        return true;
    }
    
    default void postHandle(HttpServletRequest request, HttpServletResponse response,
	Object handler, @Nullable ModelAndView modelAndView) throws Exception {}
        
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response,
	Object handler, @Nullable Exception ex) throws Exception { }
        
}

AOP

Spring AOP는 Spring에서 지원하는 관점 지향 프로그래밍을 구현할 수 있는 기술이다.

사용 기준

그러면 언제 Filter를 사용하고, 언제 Interceptor를 사용할까?

 

가장 큰 차이는 아래 두 가지이다.

  • 실행 시점이 다르다.
  • 필터는 Web Application에 등록하고, 인터셉터는 Spring Context에 등록한다.

 

필터

필터는 Servlet에서 처리하기 전후를 다룰 수 있고, 주로 스프링과 무관하게 전역적으로 처리하는 작업들을 수행할 때 사용할 수 있다.

예를 들어 XSS 방어를 Filter에 구현하면 악의적인 요청이 스프링 컨테이너까지 전달되기도 전에 차단하므로 안전성을 더욱 높일 수 있다. 이미지/데이터 압축 및 문자열 인코딩 변환 등을 가장 앞단에서 처리할 때도 사용할 수 있다.

 

필터는 아래와 같이 ServletRequest, Servlet Response를 교체하는 것도 가능하다. (인터 셉터는 HttpServletRequest, HttpServletResponse를 파라미터로 받는다.)

public class SomeFilter implements Filter {  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        chain.doFilter(new CustomServletRequest(), new CustomResponse());
    }
}

이러한 점은 Request의 Payload를 로깅할 때 사용할 수 있다. HttpServletRequest의 Body는 InputStream을 통해서 한 번만 읽을 수 있다. 즉, 앞 단에서 요청을 읽으면 컨트롤러에서는 해당 요청 본문을 읽을 수 없다.

 

그래서 아래와 같이 ServletRequest를 직접 구현한 CachedBodyServletRequestWrapper로 변환할 수 있다.

public class SomeFilter implements Filter {
  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        chain.doFilter(new ContentCachingRequestWrapper(request), response);
    }
}

추가로 중요한 점은 필터는 Web Application에 등록되므로 예외가 발생하면 Web Application에서 처리된다. 즉, Tomcat에서 error-page를 구성하는 등의 처리가 필요하게 된다.

 

인터셉터

인터셉터의 경우에는 Controller에 넘겨주는 데이터를 가공할 때 사용할 수 있다. 예를 들면 JWT 토큰 정보를 파싱해서 컨트롤러에게 해당 유저의 권한을 전달해주는 처리를 구현할 있다. 추가로 핸들러와 어떤 컨트롤러가 매핑되었는 지를 알 수 있으므로, 각 컨트롤러의 권한 차이를 둘 수도 있다.

 

추가로 Handler 전후뿐 아니라, View를 렌더링한 이후 등에 대한 시점에서도 처리가 가능하다.

 

그리고 필터와 비교했을 때 인터셉터는 스프링의 모든 빈 객체에 접근이 가능하다는 차이를 가진다.

 

인터셉터에서 예외가 발생하면 DispatcherServlet이 받기 때문에 @ControllerAdvice, @ExceptionHandler 등으로 처리가 가능하다.

 

AOP

AOP의 Advice는 로깅, 트랜잭션, 에러 처리 등 비즈니스 단에서의 메서드를 더 세밀하고 조정하고 싶을 때 사용한다. 인터셉터와 달리 주소(URL), 파라미터, 애노테이션 등 PointCut이 지원하는 다양한 방법으로 대상을 지정할 수 있다.

 

즉, 필터와 인터셉터는 요청과 응답 시 DisplatcherServlet이나 Handler 주변에서 동작한다. 반면, AOP는 비즈니스 단에서도 동작이 가능하다는 장점이 있다.

 

요약 정리

  • 필터는 자바(Java)가 지원하는 기능이고, 인터셉터는 스프링(Spring)이 지원하는 기능이다.
  • 필터는 WebApplication에서 동작하고, 인터셉터는 Spring Context에서 동작한다.
    • 필터에서 발생하는 예외는 WebApplication에서 처리된다.
  • 필터는 Dispatcher Servlet보다도 앞에서 동작할 수 있다.
    • ServletRequest, ServletResponse를 받아서 처리하는 것이 가능하다.
  • 인터셉터는 필터랑 달리 컨트롤러가 동작한 후에 작업을 처리할 수 있다.
    • ex. ViewController에서 뷰를 생성한 것에 따라 동적으로 처리하는 일이 가능하다.

 


Reference