Filter 와 Interceptor의 차이와 Spring Application에서의 역할

김유정·2024년 5월 12일
0

이미지 참고: https://www.baeldung.com/spring-mvc-handlerinterceptor-vs-filter

Filter

  • 필터는 DispatcherServlet이 실행되기 전 스프링 컨테이너 밖에서 실행된다.
  • 서블릿에 도달하는 것을 조작하고 차단할 수도 있고, 반대로 응답이 클라이언트에 도달하지 못하도록 처리할 수 있다.
  • Spring Security 는 인증과 인가를 위해 필터를 사용하는 좋은 예시이다.

구현

  • 필터를 추가하기 위해선 jakarta.servlet.Filter 인터페이스를 구현해야한다.
public interface Filter {
    // 필터가 처음으로 생성될 때 한 번 초기화를 위해 호출
    // 리소스를 초기화하거나 설정을 읽어들이는 데 사용됨
    default void init(FilterConfig filterConfig) throws ServletException {
    }

	// 필터링 작업 수행
    // 클라이언트의 요청을 가로채고, 필터 체인을 따라 다음 필터에 요청을 전달하거나 서블릿으로 전달
    // 예외를 던지거나 다음 필터 또는 서블릿을 호출하지 않으면 요청이 중단될 수 있음
    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException;

	// 필터가 소멸될 때 호출
    default void destroy() {
    }
}

필터는 다음 필터를 호출할 때 request와 response를 넘겨주기 때문에, 해당 값을 특정 로직에 따라 처리하여 원하는 값으로 넘겨줄 수 있다.

public class MyFilter implements Filter {
	@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	    // 다른 request와 response를 넣어줄 수 있음        
	    chain.doFilter(request, response);    
    }
}

Interceptor

  • Interceptor는 스프링 컨텍스트 내에서 동작하며, 컨트롤러에 도달하기 전 그리고 뷰가 렌더링 되기 전이나 후에 요청을 가로챌 수 있다.
  • Dispacher Servlet이 핸들러 매핑을 통해 컨트롤러를 찾도록 요청하는데, 그 결과로 실행 체인(HandlerExecutionChain)을 돌려준다. 여기서 1개 이상의 인터셉터가 등록되어 있다면 순차적으로 인터셉터를 거쳐 컨트롤러가 실행되게 한다.

구현

  • 인터셉터를 추가하기 위해선 HanlderInterceptor 인터페이스를 구현해야한다.
  • preHandle() 메서드를 통해서 컨트롤러가 실행되기 이전에 특정 작업을 수행하고 다음 단계로 넘어가게 할것인지 말것인지 지정할 수 있다.
  • postHandle()이나 afterCompletion() 메서드를 통해 컨트롤러 호출 이후 작업을 정의할 수 있지만, void 이기 때문에 응답을 조작할 수는 없다.
public interface HandlerInterceptor {
	// 컨트롤러가 호출되기 전 실행
    // true면 다음 인터셉터가 진행되거나 컨트롤러 메서드가 수행된다.
	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 {
	}

}

각각 언제 실행되는지는 알겠는데, 잘 와닿지는 않는다. 이를 위해서는 DispatcherServlet을 알 필요가 있어보인다.

용어 및 개념 정리

Servlet

  • 사용자와 상호작용을 하는 동적인 프로그램을 만들기 위해 CGI(Common Gateway Interface) 라는 규칙을 만들었다. CGI는 응용 프로그램 간에 데이터를 주고받기 위한 방법이나 규약을 뜻한다.
  • Java에서 Servlet은 CGI와 비슷하게 웹서버와 상호작용하기 위한 규칙을 정의해놓은 인터페이스이다.

Web Server

  • 큰 의미로는 웹 서비스를 제공하는 서버라고도 볼 수 있지만, 좁은 의미로는 정적 콘텐츠를 제공하는 역할을 한다.

Web Application Server(WAS)

  • 정적 콘텐츠 뿐만 아니라 동적 콘텐츠까지 처리할 수 있다.

Dispatcher Servlet

각각의 용어에 대해서 어렴풋이 개념은 알겠지만, 나는 Web Server와 Web Application Server를 구분해서 애플리케이션을 만들지 않았었는데 어떻게 동작했던 것일까?

Spring application 아키텍처

스프링에서는 Tomcat이 Web Server와 Servlet Container 역할을 하며, 아래와 같이 아키텍쳐가 구성되어 있다고 한다.


이미지 참고: https://taes-k.github.io/2020/02/16/servlet-container-spring-container/

  • DispatcherServlet은 javax.servlet.Servlet 인터페이스를 스프링에서 구현한 것으로 스프링 컨테이너 내에서 생성되고 빈으로 관리되고, 서블릿 컨테이너(Tomcat)가 이를 실행 및 관리한다.
  • 필터는 일반적으로 스프링 컨테이너 밖에서 처리되지만, 스프링에서 제공하는 CorsFilter나 Security 관련 Filter와 같은 일부 필터는 스프링 컨테이너 내에서 처리된다. 이러한 필터들은 스프링의 IoC 컨테이너에 의해 관리되며, DispatcherServlet 이전에 처리된다.

참고

0개의 댓글