ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] 필터(Filter)와 인터셉터(Interceptor)
    Spring 2024. 7. 21. 02:46

    Spring에서 공통적으로 여러 작업을 처리하고 중복된 코드를 제거 및 재가공하는 많은 기능을 가지고 있다.

    그 중 필터와 인터셉터라는 기능이 있고 이 둘의 공통점으로 Controller에 도달하기 전 처리되는 기능이지만, 역할이 다르므로 이 둘의 정의와 차리를 알아보자.


    1. 필터

    필터는 말 그대로 요청과 응답을 거른 뒤에 정제하는 역할을 한다.

     

    디스패처 서블릿(Dispatcher Servlet)에 요청이 전달되기 전, 후에 url 패턴에 맞는 모든 요청에 대해 부가 작업을 처리할 수 있는 기능을 제공한다.

     

    디스패처 서블릿이란?

     

    디스패처 서블릿은 스프링의 가장 앞단에 존재하는 웹에서 이뤄지는 컨트롤러이므로, 필터는 스프링 범위 밖에서 처리가 되는 것 즉, 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리가 되고, 스프링의 범위 밖에서 처리가 되는 것이다.

     

     

    필터 주요 메서드

    init() - 필터 인스턴스 초기화 시 실행되는 메서드
    doFilter() - 클라이언트의 요청/응답 처리 시 실행되는 메서드
    destroy() - 필터 인스턴스가 제거될 때 실행되는 메서드

     

    필터 사용사례

    - 보안 및 인증/인가 관련 작업
    - 모든 요청에 대한 로깅 또는 검사
    - 이미지/데이터 압축 및 문자열 인코딩
    - XSS 방어, CORS
    - Spring과 분리되어야 하는 기능

     

    OncePerRequestFilter

    서블릿은 사용자의 요청을 받으면 서블릿을 생성해 메모리에 저장해두고, 같은 클라이언트의 요청을 받으면 생성해둔 서블릿 객체를 재활용하여 요청을 처리한다.

     

    문제는 이 서블릿이 다른 서블릿으로 dispatch되는 경우가 있을 수 있다.

     

    가장 대표적으로 Spring Security에서 인증과 접근 제어 기능이 Filter로 구현되어진다.

     

    이러한 인증과 접근 제어는 RequestDispatcher 클래스에 의해 다른 서블릿으로 dispatch되게 되는데, 이 때 이동할 서블릿에 도착하기 전에 다시 한번 filter chain을 거치게 된다.

     

    바로 이 때 또 다른 서블릿이 우리가 정의해둔 필터가 Filter나 GenericFilterBean로 구현된 filter를 또 타면서 필터가 두 번 실행되는 현상이 발생할 수 있다.

     

    이런 문제를 해결하기 위해 등장한 것이 바로 OncePerRequestFilter이다.

     

    이 추상 클래스를 구현한 필터는 사용자의 한번에 요청 당 딱 한번만 실행되는 필터를 만들 수 있다.


    2. 인터셉터

    인터셉터는 말 그대로 가로채는 녀석이다.
    그렇다면 뭘 가로챌까? 프론트엔드에서 받는 요청을 가로채는 것이 아닌 Dispatcher Servlet이 Controller를 호출하기 전/후에 인터셉터가 가로채는 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공한다.

     

    이번엔 필터와 달리 웹 컨테이너가 아닌 Spring 내부 컨텍스트에서 처리가 되고, Spring MVC에서 제공되는 기능이다.

     

    인터셉터 메소드

    인터셉터를 추가하기 위해서는 org.springframework.web.servlet의 HandlerInterceptor 인터페이스를 구현(implements)해야 하며, 이는 다음의 3가지 메소드를 가지고 있다.

    public interface HandlerInterceptor {
    	/* Controller가 호출되기 전에 실행 */
        default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
            return true;
        }
        
        /* Controller가 호출된 후에 실행 */
        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 {
        }
    }

     

    인터셉터 사용사례

    - 세부적인 보안 및 인증/인가 공통 작업
    - API 호출에 대한 로깅 또는 검사
    - Controller로 넘겨주는 정보(데이터)의 가공

    3. 필터(Filter)와 인터셉터(Interceptor)의 사용 사례

    필터(Filter) 는 특정 요청과 컨트롤러에 관계없이 전역적으로 처리해야 하는 작업이나 웹 어플리케이션에 전반적으로 사용되는 기능을 구현할 때 적용하고,
    인터셉터(Interceptor) 는 클라이언트의 요청과 관련된 작업에 대해 추가적인 요구사항을 만족해야 할 때 적용한다.
Designed by Tistory.