ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Filter, Interceptor
    🌱 spring 2022. 10. 11. 14:30

    Spring은 공통적으로 여러 작업을 처리해 중복된 코드를 제거할 수 있도록 많은 기능을 지원한다.

    • 필터(Filter) vs 인터셉터(Interceptor)
    • 인터셉터와 AOP

    📌 필터(Filter)


    💡 필터(Filter)는 Dispatcher Servlet에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공한다.

    Dispatcher Servelt은 스프링의 가장 앞단에 존재하는 프론트 컨트롤러이므로, 필터는 스프링 범위 밖에서 처리가 된다.

    ⇒ 일반적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 때 사용한다.

     

    즉, 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리가 된다

    • 스프링 빈으로 등록은 된다.
    • 디스패처 서블릿 전 / 후에 처리

    HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 처리한다.

    • Request / Response에 대한 조작이 가능하다
    • 유일하게 ServletRequest, ServletResponse 객체를 변환할 수 있다.

    Spring Framework에서는 주로 request/response의 logging 용도로 활용하거나, 인증과 관련된 로직을 필터에서 처리한다.

    필터의 메서드

    필터를 추가하기 위해서는 javax.servlet의 Filter 인터페이스를 구현(implement)해야한다.

    • init()
    • doFilter()
    • destroy()
    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() {}
    }
    

    init()

    • 필터 객체를 초기화하고 서비스에 추가하기 위한 메소드 (웹 컨테이너가 호출)
    • 이후 요청들은 doFilter를 통해 처리된다.

    doFilter()

    • url pattern에 맞는 모든 HTTP 요청이 dispatcher servlet으로 전달되기 전에 실행되는 메소드
    • 필터의 파라미터인 FilterChain의 doFilter를 통해 다음 대상으로 요청을 전달하게 된다.

    destroy()

    • 필터 객체를 서비스에서 제거하고 사용하는 자원을 반환하기 위한 메소드
    • 웹 컨테이너가 1번 호출하고 이후에는 doFilter에 의해 처리되지 않는다.

    대표적으로 필터를 인증과 인가에 사용하는 도구로는 SpringSecurity가 있다.

    • SpringSecurity의 특징 중 하나는 SpringMVC에 종속적이지 않다는 것.
    • 이러한 이유로 필터 기반으로 인증/인가 처리를 한다.

    📌 인터셉터 (Interceptor)


    💡 인터셉터(Interceptor)는 필터와 달리 Spring이 제공하는 기술이다.
    디스패처 서블릿이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공한다.

    즉, 인터셉터는 스프링 컨텍스트에서 동작을 한다.

     

    Dispatcher Servlet은 내부적으로 핸들러 매핑을 통해 적절한 컨트롤러를 찾도록 요청한다.

    • 이 결과로 실행 체인(HandlerExecutionChain)을 반환한다.

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

    인터셉터의 메소드

    인터셉터를 추가하기 위해서는 org.springframework.web.servlet의 HandlerInterceptor 인터페이스를 구현(implements)해야 한다.

    • preHandle()
    • postHandle()
    • afterCompletion()
    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 {
        }
    }
    

    preHandle()

    • 컨트롤러가 호출되기 전에 실행된다.
    • 컨트롤러 이전에 처리해야 하는 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우 사용
    • 반환 타입이 boolean이다
      • true일시 다음 단계로 진행이 된다.
      • false이면 작업을 중단하여 이후 작업이 진행되지 않는다.

    postHandle()

    • 컨트롤러가 호출된 후에 실행된다.
    • 컨트롤러 이후에 처리해야 하는 후처리 작업이 있을 때 사용할 수 있다.
    • 컨트롤러 하위 계층에서 예외가 발생하면 postHandle()은 호출되지 않는다.

    afterCompletion()

    • 모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행
    • 요청 처리 중 사용한 리소스를 반환할 때 사용하기 적합하다.
    • postHandle() 과 달리 컨트롤러 하위 계층에서 예외가 발생해도 반드시 호출된다.

    🆚 필터 와 인터셉터의 차이 및 용도


    필터와 인터셉터는 각각 관리되는 컨테이너와 Request / Response 조작가능 여부가 다르고 용도도 다르다.

    대상 필터(Filter 인터셉터(Interceptor)

    대상 필터(Filter) 인터셉터(Interceptor)
    관리되는 컨테이너 웹 컨테이너 스프링 컨테이너
    Request / Response
    - 객체 조작 가능 여부
    O X
    용도 - 공통된 보안 및 인증 / 인가 관련 작업
    - 모든 요청에 대한 로깅 또는 검사
    - 이미지 / 데이터 압축 및 문자열 인코딩
    - Spring과 분리되어야 하는 기능
    - 세부적인 보안 및 인증 / 인가 관련 작업
    - API 호출에 대한 로깅 또는 검사
    - Controller로 넘겨주는 정보(데이터) 가공
    필터는 스프링 빈으로 등록 가능하고 다른곳에 주입되거나 다른 빈을 주입받을 수도 있다.

    Request / Response 객체 조작 가능 여부

    필터는 request와 response를 조작할 수 있지만 인터셉터는 조작할 수 없다.

    조작

    • 내부 상태를 변경 ❌
    • 다른 객체로 바꿔친다는 의미

    필터는 다른 필터를 호출하기 위해서 필터 체이닝을 해준다.

    • 이때, request와 response 객체를 넘겨주는데
    • 우리가 원하는 request, response 객체를 넣어줄 수 있다.

    반면, 인터셉터는 필터와 다르다.

    • 인터셉터는 true를 반환하면 다음 인터셉터가 실행되거나 컨트롤러로 요청이 전달되고,
    • false를 반환하면 요청이 중단된다.
    • 따라서, request, response 객체를 넘겨줄 수 없다.

    용도

    필터는 스프링과 무관하게 전역으로 처리해야 하는 작업들을 처리할 수 있다.

    • 웹 애플리케이션에 전반적으로 사용되는 기능을 구현
    • ServletRequest / ServletResponse 객체를 조작할 수 있다는 점에서 인터셉터보다 훨씬 강력하다.

    인터셉터는 클라이언트의 요청과 관련되어 전역적으로 처리해야 하는 작업들을 처리할 수 있다.

    • 인증이나 인가와 같이 클라이언트 요청과 관련된 작업등
    • HttpServletRequest, HttpServletResponse 등과 같은 객체를 제공받으므로 객체 자체는 조작할 수 없다.
      • 대신 객체 내부적으로 갖는 값을 조작할 수 있다.→ ex) 사용자의 정보를 HttpServletRequest에 넣어줄 수 있다.
      • → 컨트롤러로 넘겨주기 위한 정보를 가공

     

    참고 자료

    https://mangkyu.tistory.com/173

    https://velog.io/@lovi0714/필터Filter와-인터셉터Interceptor

    https://velog.io/@miot2j/Spring-Filter-Interceptor-AOP-차이-및-AOP를-사용하여-Logging을-구현한-이유

    https://velog.io/@ansalstmd/스프링부트-다양한-기능-5.-Spring-Boot-Filter와-Interceptor

    https://catsbi.oopy.io/9ed2ec2b-b8f3-43f7-99fa-32f69f059171

    '🌱 spring' 카테고리의 다른 글

    JPA - Embedded Type  (0) 2022.11.02
    Spring Scheduler  (0) 2022.10.24
    OSIV 🧐  (0) 2022.10.11
    JPA - N + 1 문제  (0) 2022.10.11
    영속성 컨텍스트  (0) 2022.10.11

    댓글

Designed by Tistory.