필터와 인터셉터

전성수·2024년 5월 23일

면접 준비 해보기

목록 보기
5/5

공통적으로 여러 작업을 처리함으로써 중복된 코드를 제거하도록 하는 기능.

필터

디스패처 서블릿에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가 작업을 처리할 수 있는 기능 제공.
디스패처 서블릿은 스프링의 가장 맢단에 존재하는 프론트 컨트롤러이므로, 필터는 스프링 범위 밖에서 처리.
스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너(서블릿 컨테이너)에 의해 관리가 되는 것.

  • 필터를 추가하기 위해서는 Filter 인터페이스를 구현해야함
    • init, doFilter, destroy 매서드를 가지고 있음
    • init : 필터 객체를 초기화하고 서비스에 추가하기 위한 매서드
    • doFilter : url-pattern에 맞는 모든 HTTP 요청이 디스패처 서블릿으로 전달되기 전에 웹 컨테이너에 의해 실행되는 매서드.
      • FilterChain 을 파라미터로 받아서 다음 대상으로 요청을 전달.
      • chain.doFilter 전/후에 우리가 필요한 처리 과정을 넣어줌으로써 원하는 처리를 진행
    • destroy : 필터 객체를 서비스에서 제거하고 사용하는 자원을 반환하기 위한 매서드.

인터셉터

디스패처 서블릿이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공.
웹 컨테이너(서블릿 컨테이너)에서 동작하는 필터와 달리 스프링 컨텍스트에서 동작하는 것.

  • 인터셉터를 추가하기 위해서는 HandlerInterceptor 인터페이스를 구현해야 하며 이는 다음의 3가지 매서드를 가지고 있음.
    • preHandle, postHandle, afterCompletion 매서드
    • preHandle : 컨트롤러가 호출되기 전에 실행. 전처리 작업이나 요청 정보를 가공하는 경우
      • 반환 타입이 boolean이라 true이면 다음 단계 진행, false라면 작업 중단
    • postHandle : 컨트롤러가 호출될 후 실행
    • afterCompletion : 모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행됨
      • 요청 처리 중에 사용한 리소스를 반환할 때 사용하기에 적합
  • 인터셉터/AOP 비교
    • 다음과 같은 이유들로 컨트롤러의 호출 과정에 적용되는 부가기능들은 인터셉터를 사용하는 편이 나음
    • 컨트롤러는 타입과 실행 메소드가 모두 제각각이라 포인트컷의 작성이 어려움
    • 컨트롤러는 파라미터나 리턴 값이 일정하지 않음
    • AOP에서는 req,res 객체를 얻기 어렵지만 인터셉터에서는 파라미터로 넘어옴

필터와 인터셉터

  • 컨테이너

    • 필터와 인터셉터는 관리되는 영역이 다름
    • 필터는 스프링 이전의 서블릿 영역에서 관리되지만, 인터셉터는 스프링 영역에서 관리되는 영역이기 때문에 필터는 스프링이 처리해주는 내용들을 적용 받을 수 없음.
      • 필터는 스프링에 의한 예외처리가 되지 않음
  • 스프링의 예외 처리 여부

    • 일반적으로 스프링을 사용하면 ControllerAdvice와 ExceptionHandler를 이용한 예외처리 기능을 주로 사용.
    • 하지만 필터는 스프링의 앞의 서블릿 영역에서 관리되기 때문에 스프링의 지원을 받을 수 없음.
    • 그래서 필터에서 Exception이 던져지면 에러가 처리되지 않고 서블릿까지 전달.
    • 서블릿은 예외가 핸들링 되기를 기대했지만 예외가 그대로 올라와서 예상치 못한 Exception을 만나 500 응답.
  • req,res 객체 조작 가능 여부

    • 필터는 req, res 객체를 바꿀 수 있지만 인터셉터는 아님.

    필터

  • 공통된 보안 및 인증/인가 관련 작업

  • 모든 요청에 대한 로깅 또는 감사

  • 이미지/ 데이터 압축 및 문자열 인코딩

  • Spring과 분리되어야 하는 기능

    필터에서는 기본적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 수 있음.

  • 보안 공통 작업 : 필터는 인터셉터보다 앞단에서 동작하므로 전역적으로해야하는 보안 검사를 해서 올바른 요청이 아닐 경우 차단을 할 수 있음.

    • 스프링 컨테이너까지 요청이 전달되지 못하고 차단되므로 안정성을 더 높일 수 있음.
  • 필터는 이미지나 데이터의 압축이나 문자열 인코딩과 같이 웹 애플리케이션에 전반적으로 사용되는 기능을 구현하기 적당함.

  • req,res 객체를 조작할 수 있다는 점에서 인터셉터보다 강력함

    인터셉터

  • 세부적인 보안 및 인증/인가 공통 작업

  • API 호출에 대한 로깅 또는 감사

  • Controller로 넘겨주는 정보의 가공

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

  • req,res 객체를 가공할 수 있음

    • 사용자의 ID를 기반으로 조회한 사용자 정보를 HttpServletRequest에 넣어줄 수 있음

DelegatingFilterProxy

서블릿 컨테이너에서 관리되는 프록시용 필터로써 우리가 만든 필털르 가지고 있음
우리가 만든 필터는 스프링 컨테이너의 빈으로 등록되는데 요청이 오면 DelegatetingFilterProxy가 요청을 받아서 우리가 만든 필터에게 요청을 위임함
1. Filter 구현체가 스프링 빈으로 등록됨
2. ServletContext가 Filter 구현체를 갖는 DelegatingFilterProxy를 생성함
3. ServletContext가 DelegatingFilterProxy를 서블릿 컨테이너에 필터로 등록
4. 요청이 오면 DelegatingFilterProxy가 필터 구현체에게 요청을 위임하여 필터 처리를 진행함

  • SpringBoot가 등장한 이후
    • DelegatingFilterProxy에 등록할 필요가 없음
    • SpringBoot가 내장 웹서버를 지원하면서 톰캣과 같은 서블릿 컨테이너까지 SpringBoot가 제어가능하기 때문.
    • SpringBoot가 서블릿 필터의 구현체 빈을 찾으면 DelegatingFilterProxy없이 바로 필터 체인에 필터를 등록해주기 때문
  • 등장 배경 : 필터에서 다른 스프링 빈의 주입이 필요해짐
  • 등장 이전 : 스프링 빈으로 등록 및 다른 빈 주입이 불가능 했음
  • 등장 이후 : DelegatingFilterProxy를 통해 스프링 빈으로 등록 및 다른 빈 주입이 가능해짐
  • SpringBoot의 등장 이후 : 웹서버를 직접 관리하면서 DelegatingFilterProxy 조차 필요없게 됨.

출처

망나니개발자님 블로그

profile
ㅡ/ㅡ

0개의 댓글