Filter & Interceptor

@Wonyu· February 27, 2025 · 4 min read

Filter와 Interceptor는 Spring에서 요청을 가로채 처리할 수 있는 두 가지 주요 컴포넌트
두 컴포넌트 모두 요청(Request)과 응답(Response)에 대해 사전/사후 처리를 수행할 수 있지만, 동작 시점과 적용되는 범위가 다름

📌 Spring Filter

✅ WAS 레벨에서 동작
✅ DispatcherServlet 요청 전 실행 filter

주요 메서드

public interface Filter {
    void init(FilterConfig filterConfig) throws ServletException;
    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
    void destroy();
}

🔹 doFilter()

  • 모든 요청을 가로채어 특정 처리를 수행
  • chain.doFilter(request, response)를 호출하지 않으면 요청이 DispatcherServlet으로 전달되지 않음

🔹 init()

  • 필터가 처음 생성될 때 한 번만 실행되는 초기화 메서드

🔹 destroy()

  • 필터가 제거될 때 한 번 실행되는 정리 작업 메서드

Filter & Bean

✅ Filter는 WAS에 의해 관리되는 서블릿 컴포넌트였기 때문에 Bean으로 등록할 수 없었음
✅ Filter에서도 Spring 기술을 필요로 하는 상황이 많아지면서 Bean으로 등록 가능해짐

🔹 DelegatingFilterProxy
✅ Spring Application Context의 Filter 클래스를 Servlet Filter에 등록할 수 있도록 해주는 객체

CustomFilter.java

@Component("loggingFilter")
public class CustomFilter implements Filter {

    private static Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);

    @Override
    public void init(FilterConfig config) throws ServletException {
        // initialize something
    }

    @Override
    public void doFilter(
      ServletRequest request, ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {
 
        HttpServletRequest req = (HttpServletRequest) request;
        LOGGER.info("Request Info : " + req);
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // cleanup code, if necessary
    }
}

ApplicationInitializer.java

public class ApplicationInitializer 
  extends AbstractAnnotationConfigDispatcherServletInitializer {
    // some other methods here
 
    @Override
    protected Filter[] getServletFilters() {
        DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy();
        delegateFilterProxy.setTargetBeanName("loggingFilter");
        return new Filter[]{delegateFilterProxy};
    }
}

🔹 Spring Boot 등장
Spring Boot 등장 이후, Spring Boot가 내장 웹서버를 지원하면서 ServletContext를 직접 제어할 수 있기 때문에 위와 같은 과정 없이도 Filter 빈을 Filter Chain에 등록할 수 있게 되었다.

📌 Spring Interceptor

✅ Spring MVC에서 DispatcherServlet 이후, 컨트롤러로 요청이 가기 전후에 실행되는 컴포넌트
✅ Handler(Controller)를 실행하기 전/후에 특정 로직을 수행할 수 있도록 도움 interceptor

필요한 상황

  • API 요청 감사 또는 로깅
  • 인증/인가 체크
  • 요청 데이터 가공 컨트롤러 실행 전후에 필요한 공통 로직을 구현할 때 유용

주요 메서드

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, ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

🔹 preHandle()
요청을 가로채 컨트롤러 실행 전에 수행

🔹 postHandle()
컨트롤러 실행 후, View 렌더링 전에 작업 수행

🔹 afterCompletion()
요청 처리가 완료된 후 실행(예외가 발생하더라도 실행)


📌 참고

https://www.baeldung.com/spring-delegating-filter-proxy
https://mangkyu.tistory.com/221
https://www.baeldung.com/spring-mvc-handlerinterceptor
https://mangkyu.tistory.com/173

@Wonyu
Hello :) I'm Wonyu