본문 바로가기

공부 정리/Java

Filter vs Interceptor 차이 (Spring)

728x90
반응형

개요


Filter와 Interceptor는 모두 요청을 받을 때, 특정 조건으로 제한을 하거나 변경을 할 때 사용하는 것으로 알고 있습니다. 그런데, 단순히 사용만 해보고 어디서 어떻게 작동하는지는 확인했던 적이 없습니다. 그래서 이번 기회에 정리해보겠습니다.

 

 

 

 

그림에서 알아보는 Filter와 Interceptor


Spring MVC request life cycle

 

 

  • Filter

Filter는 Web Application에서 관리되며 Spring Framework에 속하지 않습니다. 로깅, UTF-8 설정에 이용되며, 또 하나의 대표적인 예는 Spring Security가 있습니다.

 

  • Interceptor

 Interceptor는 DispatcherServlet 안에서 있으며, Spring의 Context에서 관리됩니다. 초록 배경화면을 보면 Interceptor는 Handler에 의한 유효성 검사로 Exception을 처리할 수 있습니다.

 

 

 

Servlet Filter에서부터 Web Container의 시작입니다. Filter는 Spring이 아닌 Web Container 수준에서 작동합니다.

 

Spring Context는 Dispatcher Servlet이 시작되는 곳입니다. Dispatcher Servlet과 Controller 사이에서 Interceptor는 작동합니다.

 

 

 

 

Filter


 

Filter는 HTTP 요청과 HTTP 응답에 대해 서블릿 컨테이너에 의해 실행되는 자바 클래스입니다.

 

요청들은 서블릿에 도달하기 이전에 항상 필터 객체들을 거칩니다.

 

 

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

 

  • init()

한번만 실행됩니다. 필터를 초기화하는데 사용됩니다

 

  • doFilter()

유저가 필터와 매핑되어 있는 자원에 요청을 할때마다 메서드가 실행됩니다. 필터 작업이 수행됩니다

 

 

  • destory()

필터의 작업이 모두 끝나면 한번 실행됩니다.

 

 

필터는 여러개 등록이 가능하며 @Order를 통해서 순서를 정할 수 있습니다.

 

 

 

chain은 체인 안에 있는 다음 필터로 접근을 제공합니다. 다음 과정을 진행하기 위해 필터가 요청과 응답을 통과시킵니다

public interface FilterChain {
  public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;
}

 

FilterChain은 servlet container에 의해 재공되는 객체입니다. 자원에 대한 필터가 적용된 요청의 체인 호출에 대한 보기를 제공합니다. 필터는 체인에 있는 다른 필터를 호출하기 위해 FilterChain을 이용합니다. 혹은, 호출 필터가 체인에서 마지막 필터라면, 체인의 마지막에 있는 자원을 호출합니다.

 

 

Filter는 다음과 같이 사용됩니다

인증

로깅

이미지, 데이터 압축

Spring과 결합도를 낮추기 원하는 기능들

 

 

Interceptor


 Interceptor는 서블릿 필터와 비슷합니다. 스프링 컨텍스트 접근 전처리와 후처리를 만들 수 있습니다.

 

어플리케이션은 여러 개의 인터셉터를 핸들러 그룹에 등록해서 공통 전처리를 행동을 추가할 수 있습니다.

 

HandlerInterceptor는 HandlerAdapter가 실행되기 이전에 호출됩니다. 이 메커니즘은 전처리 측면에서 넓은 분야에서 사용될 수 있습니다. 예를 들어, 인증검사 혹은 locale이나 테마변경과 같은 공통적인 핸들러 등등. 주요한 목적은 반복적인 핸들러 코드를 분리하는 것입니다.

 

public interface HandlerInterceptor {
  boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
   
  void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
    
  void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
}

 

  • preHandle()

요청을 컨트롤러에 보내기 이전에 작업을 수행할 때 사용됩니다. 이 메서드는 클라이언트에 응답을 보내기 위해서 true를 반환해야 합니다.

 

  • postHandle()

클라이언트에 응답을 보내기 이전에 작업을 수행할 때 사용됩니다

 

  • afterCompletetion()

요청과 응답이 모두 완료된 이후에 작업을 수행할 때 사용됩니다

 

HandlerInterceptor : DispatcherServlet의 내부에서 요청을 처리할 Controller를 찾습니다.

 

HandlerInterceptorAdapter : 커스텀 구현을 사용하고 싶고 일부 메서드만 관리하려면 해당 Adapter를 구현하면 됩니다

 

Interceptor는 다음과 같이 사용됩니다

- 어플리케이션 로깅과 공통 핸들러 코드 분할

- 세밀한 인증 검사

- 스프링 컨텍스트 혹은 모델 조작

 

 

Filter vs HandlerInterceptor


Filter는 Servlet API와 관련이 있으며, HnadlerInterceptor는 스프링에 한정된 개념입니다.

Interceptor는 Filter가 실행되고 난 후에 실행됩니다

인증검사 같은 세분화된 처리는 HandlerInterceptor에 적합합니다

multipart 양식, zip 압축, 이미지 처리, 로깅 요청, 인증 등의 요청 콘텐츠, 화면 콘텐츠 처리는 Filter에 적합합니다.  

Filter의 doFilter는 Interceptor의 postHandle보다 훨씬 다양한 기능을 가지고 있습니다. 요청이나 응답을 필터 체인으로 넘겨줄 수 있으며, 요청 처리를 막을 수도 있습니다.

HandlerInterceptor는 Filter에 비해 더 세분화된 조정을 할 수 있는데 왜냐하면 실제 타겟 "handler"에 접근하기 때문입니다. 

 

 

결론


Filter는 Spring MVC 밖에서 컨트롤러에 진입하기 이전에 요청을 처리할 수 있습니다. 반면에, Interceptor는 어플리케이션에 구체적으로 관심사를  분리할 때 사용합니다.

 

Filter는 체인을 통해 전달되는 요청/응답 객체들을 교환할 수 있다는 점에 더 강력합니다. filter는 web.xml에서 설정되고, HandlerInterceptor는 application context에서 정의된다는 차이를 기억해야 합니다

 

 

* 참고

 

HandlerInterceptor (Spring Framework 5.3.22 API)

Filter vs. Interceptor in Spring Boot | by Nil Seri | Medium

HandlerInterceptors vs. Filters in Spring MVC | Baeldung

https://www.linkedin.com/pulse/filter-vs-interceptor-spring-boot-omar-ismail/

 

 

728x90
반응형

'공부 정리 > Java' 카테고리의 다른 글

자바 비동기  (0) 2021.08.16
RestTemplate  (0) 2021.08.15
Validation 어노테이션 직접 만들어보기  (0) 2021.08.12
@Qualifier & @Resource & @Autowired  (0) 2021.08.12
AOP  (0) 2021.08.11