s00ng
쏭's blog
s00ng
전체 방문자
오늘
어제
  • 분류 전체보기 (69)
    • TIL (20)
      • 실습 (3)
    • Web (6)
      • React (6)
      • Basic (0)
    • JPA (5)
    • CS (3)
      • 컴퓨터 네트워크 (3)
    • Design pattern (10)
    • AWS (5)
    • ETC (0)
    • Algorithm (0)
    • Project (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기

공지사항

인기 글

태그

  • 리전
  • 가용영역
  • AWS
  • mariaDB
  • design pattern
  • EC2
  • EC2 인스턴스
  • centOS 8
  • VMware
  • solid

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
s00ng

쏭's blog

[TIL] Filter-Interceptor
카테고리 없음

[TIL] Filter-Interceptor

2025. 2. 10. 06:40
  • Filter 와 Interceptor 모두 Controller (Handler)에 요청이 오기 전과 후에 동작하여 애플리케이션 전반의 공통 관심사를 처리할 수 있다.
  • Filter는 Servlet spec, Interceptor는 Spring spec이다.
  • Filter는 FilterChain을 통해 필터를 여러개 추가하여 적용할 수 있다. Interceptor도 마찬가지이다.
  • 적용 시점은 다음과 같다.
    • 요청 → Filter → Dispatcher Servlet → Interceptor → Controller
    • Filter가 Interceptor보다 앞단에서 동작한다.
  • Interceptor 에서 발생한 예외는 ExceptionHandler로 잡을 수 있지만, Filter에서 발생한 예외는 별도로 처리해주어야한다.

 

 

Filter

HTTP 요청 → WAS → 필터 → 서블릿 → 컨트롤러

 

필터 제한

HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러 //로그인 사용자
HTTP 요청 -> WAS -> 필터 (적절하지 않은 요청이라 판단, 서블릿 호출X)  //비 로그인 사용자

 

필터에서 적절하지 않은 요청이라고 판단하면 거기에서 끝을 낼 수도 있다. 그래서 로그인 여부를 체크하기에 딱 좋다.

 

필터 체인

HTTP 요청 -> WAS -> 필터1 -> 필터2 -> 필터3 -> 서블릿 -> 컨트롤러

 

필터는 체인으로 구성되는데, 중간에 필터를 자유롭게 추가할 수 있다. 예를 들어서 로그를 남기는 필터를 먼저 적용하고, 그 다음에 로그인 여부를 체크하는 필터를 만들 수 있다.

 

필터 인터페이스

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(): 고객의 요청이 올 때 마다 해당 메서드가 호출된다. 필터의 로직을 구현하면 된다.
  • destroy(): 필터 종료 메서드, 서블릿 컨테이너가 종료될 때 호출된다.

 

 

Servlet Filter를 스프링 빈으로 등록 가능한 이유

 

  • 과거에는 Filter가 Servlet spec이기 때문에 Spring Bean으로 등록할 수 없었다.
  • 하지만, DelegatingFilterProxy가 등장함에 따라 Filter도 Bean으로 등록할 수 있다.

 

DelegatingFilterProxy

  • DelegatingFilterProxy는 서블릿 컨테이너에서 관리되는 프록시용 필터로써 개발자가 생성한 필터를 가지고 있다.
  • 개발자가 생성한 필터는 Spring Container에 Bean으로 등록되는데, 요청이 오면 DelegatingFilterProxy가 요청을 받아서 직접 생성한 필터(Spring Bean)에 요청을 위임한다.
  1. FIlter 구현체가 Bean 으로 등록됨
  2. ServletContext가 Filter 구현체를 갖는 DelegatingFilterProxy를 생성함
  3. ServletContext가 DelegatingFilterProxy를 서블릿 컨테이너에 필터로 등록함
  4. 요청이 오면 DelegatingFilterProxy가 필터 구현체에게 요청을 위임하여 필터 처리를 진행

 

SpringBoot의 등장 이후

  • SpringBoot는 내장 WAS를 사용하기때문에 톰캣과 같은 서블릿 컨테이너까지 SpringBoot가 제어할 수 있다.
  • 따라서, SpringBoot가 서블릿 필터를 구현한 Bean을 찾으면 DelegatingFilterProxy 없이 바로 FilterChain에 필터를 등록해주게된다.
  • 이로써, Filter를 Spring Bean으로 등록하여 Spring Container의 관리하에 사용할 수 있으면서 Servlet Filter에도 등록할 수 있게된다.

 

Interceptor

스프링 인터셉터 흐름

HTTP 요청 -> WAS -> 필터 -> 서블릿 -> **스프링 인터셉터** -> 컨트롤러
  • 스프링 인터셉터는 디스패처 서블릿과 컨트롤러 사이에서 컨트롤러 호출 직전에 호출 된다.
  • 스프링 인터셉터는 스프링 MVC가 제공하는 기능이기 때문에 결국 디스패처 서블릿 이후에 등장하게 된다. 스프링 MVC의 시작점이 디스패처 서블릿이라고 생각해보면 이해가 될 것이다.
  • 스프링 인터셉터에도 URL 패턴을 적용할 수 있는데, 서블릿 URL 패턴과는 다르고, 매우 정밀하게 설정할 수 있다

 

스프링 인터셉터 제한

HTTP 요청 -> WAS -> 필터 -> 서블릿 -> **스프링 인터셉터** -> 컨트롤러 //로그인 사용자

HTTP 요청 -> WAS -> 필터 -> 서블릿 -> **스프링 인터셉터**
(적절하지 않은 요청이라 판단, 컨트롤러 호출X) // 비 로그인 사용자

인터셉터에서 적절하지 않은 요청이라고 판단하면 거기에서 끝을 낼 수도 있다. 그래서 로그인 여부를 체크하기에 딱 좋다.

 

스프링 인터셉터 체인

HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 인터셉터1 -> 인터셉터2 -> 컨트롤러
  • 스프링 인터셉터는 체인으로 구성되는데, 중간에 인터셉터를 자유롭게 추가할 수 있다.
  • 예를 들어서 로그를 남기는 인터셉터를 먼저 적용하고, 그 다음에 로그인 여부를 체크하는 인터셉터를 만들 수 있다.

 

스프링 인터셉터 인터페이스

스프링의 인터셉터를 사용하려면 HandlerInterceptor 인터페이스를 구현하면 된다

public interface HandlerInterceptor {
	default boolean preHandle(HttpServletRequest request, HttpServletResponse 
	response, Object handler) throws Exception {}

	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 {}
}
  • 서블릿 필터의 경우 단순하게 doFilter() 하나만 제공된다. 인터셉터는 컨트롤러 호출 전( preHandle ), 호출 후( postHandle ), 요청 완료 이후( afterCompletion )와 같이 단계적으로 잘 세분화 되어 있다.
  • 서블릿 필터의 경우 단순히 request , response 만 제공했지만, 인터셉터는 어떤 컨트롤러( handler )가 호출되는지 호출 정보도 받을 수 있다. 그리고 어떤 modelAndView 가 반환되는지 응답 정보도 받을 수 있다.
    s00ng
    s00ng

    티스토리툴바