Spring

[Spring] Filter와 Interceptor

@leee 2023. 5. 4. 22:05

회사에서 Spring MVC 프로젝트를 Spring Boot로 변경하여 재구축하는 업무를 맡았다. MVC와 Boot가 대부분은 비슷하게 이루어져 있었지만, 몇 가지 설정하는 작업이 조금은 달랐다. 그러다가 Interceptor가 설정된 부분에 오류가 발생하여 찾아보게 되었고, 예전에 Spring Cloud Gateway 환경에서 API Gateway를 개발할 때 사용되던 Filter와 어떤 점이 다른지 궁금해졌다.

 

Filter

Filter는 Spring Framework가 아닌 웹 서버의 일부분으로, 들어오는 HTTP 요청을 차단 시키거나 조작하는 기능을 제공한다.

 

쉽게 Spring Security를 생각하면 되는데, Spring Security에서는 Filter를 이용해 인증/인가에 따라 요청을 제한 시킬 수 있다.

Filter를 사용하여 요청이 오면 그 주소를 더해 로그를 찍어주는 예제이다.

 

@Component
public class LogFilter implements Filter {

    private Logger logger = LoggerFactory.getLogger(LogFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException {
        logger.info("Hello from: " + request.getLocalAddr());
        chain.doFilter(request, response);
    }

}

 

  • 어노테이션 @Component를 달아서 Spring Context에 추가시켜야 한다.
  • doFilter() 메서드는 HTTP 요청이 오면 호출되어 메서드 안의 로직을 수행할 수 있게 해준다. 요청을 확인하거나, 들어오는 요청/응답을 필터링하거나, filter chain으로 다음 필터 로직을 수행할 수도 있다.

 

Interceptor

Interceptor는 Filter와 유사하지만, Controller로 가는 요청에 대해 작업의 전처리와 후처리를 할 수 있게 해준다.

 

다음은 Interceptor를 이용해서 로그 처리를 하는 예제이다.

 

public class LogInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
      throws Exception {
        logger.info("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 
      throws Exception {
        logger.info("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 
      throws Exception {
        logger.info("afterCompletion");
    }

}

 

  • Spring에서는 HandlerInterceptor 인터페이스를 제공해 Interceptor를 쉽게 구현할 수 있다.
  • preHandle() : 요청 전에 수행되는 메서드
  • postHandle() : 요청 후 응답을 보내기 전(view가 rendering 되기 전) 수행되는 메서드
  • afterCompletion() : 요청과 응답 모두 처리 완료 후(view가 rendering 되고 난 후) 수행되는 메서드

 

Filter와 Interceptor의 차이점

 

먼저 HTTP 요청/응답에 따른 흐름과 Filter, Interceptor의 구조는 다음과 같다.

 

https://www.baeldung.com/spring-mvc-handlerinterceptor-vs-filter#key-differences-and-use-cases

 

Filter는 DispatcherServlet 앞에 존재하며, DispatcherServlet을 도달하기 전에 요청/응답을 가로채 기능을 수행한다. 따라서 인증, 로그 처리, Auditing, 이미지나 데이터 압축, Spring MVC와 분리되는 기능 등 전체적인 작업에 더 적합하다.

 

반면 Interceptor는 DispatcherServlet과 Controller 사이에 위치해 Spring MVC 내부에 존재한다. Handler나 ModelAndView 객체에 접근이 가능하며, cross-cutting 문제 처리, 세부적인 권한 검사, Spring context나 Model 조작 등 세분화된 작업을 수행하는 데 적합하다.

 

 

References