Spring MVC 내 HandlerInterceptors vs. Filters

2024. 2. 16. 20:38프로그래밍

728x90

https://www.baeldung.com/spring-mvc-handlerinterceptor-vs-filter

 

1. 개요

이 글에서 우리는 Java 서블릿 필터와 Spring MVC HandlerInterceptor를 비교해보고 어떤 때 어느 것이 다른 것보다 더 나은지 비교 해 볼것입니다.

2. 필터

필터는 Spring 프레임워크가 아닌 웹서버의 한 부분입니다. 들어오는 요청의 경우 우리는 이런 필터들을 사용하여 요청이 서블릿에 도달하지 못하도록 조작하고 차단할 수도 있습니다. 그 반대로 응답이 클라이언트에 도달하지 못하도록 차단할 수도 있습니다.

Spring Security는 인증 및 권한 부여에 필터를 사용하는 정말 좋은 예중 하나입니다. Spring Security를 ​​구성하려면 DelegatingFilterProxy라는 단일 필터를 추가하기만 하면 됩니다. 이렇게하면 Spring Security는 들어오고 나가는 모든 트래픽을 가로챌 수 있습니다. 이것이 Spring Security가 Spring MVC 외부에서 사용될 수 있는 이유입니다.

2.1. Filter 만들기

필터를 생성하려면 우선 javax.servlet.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);
    }

}


다음으로 ServletRequest, ServletResponse 또는 FilterChain 개체에 액세스하거나 조작할 수 있는 doFilter 메서드를 재정의합니다. 우리는 이 FilterChain 객체를 사용하여 요청을 허용하거나 차단할 수 있습니다.

마지막으로 @Component로 주석을 달아 Spring 컨텍스트에 필터를 추가합니다. 나머지는 Spring이 알아서 해 줄 것입니다.

3. 핸들러인터셉터

HandlerInterceptors는 Spring MVC 프레임워크의 일부이며 DispatcherServlet과 우리의 컨트롤러 사이에 위치합니다. 우리는 요청이 컨트롤러에 도달하기 전, 뷰가 렌더링되기 전과 후에 요청을 가로챌 수 있습니다.

3.1. HandlerInterceptor 생성

HandlerInterceptor를 생성하기 위해 org.springframework.web.servlet.HandlerInterceptor 인터페이스를 구현하는 클래스를 생성합니다. 이 클래스는 세 가지 메서드를 재정의할 수 있는 옵션을 제공합니다:

  • preHandle() – 대상 핸들러가 호출되기 전에 실행됩니다.
  • postHandle() – 대상 핸들러 이후, DispatcherServlet이 뷰를 렌더링하기 전에 실행됩니다.
  • afterCompletion() – Callback after completion of request processing and view rendering
  • afterCompletion() – 요청 처리 및 뷰 렌더링 완료 후 콜백
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");
    }

}

 

4. 주요 차이점 및 사용 사례

요청/응답 흐름에서 필터와 HandlerInterceptor에 대한 적합한 위치를 보여주는 다이어그램을 살펴봅시다:


필터는 요청이 DispatcherServlet에 도달하기 전에 가로채서 다음과 같은 대략적인 작업에 이상적으로 사용 됩니다:

  • 인증 - Authentication
  • 로깅 및 감사  - Logging and auditing
  • 이미지와 데이터 압축
  • Spring MVC에서 분리하려는 모든 기능

반면에 HandlerIntercepors는 DispatcherServlet과 컨트롤러 간의 요청을 가로챕니다. 이는 Spring MVC 프레임워크 내에서 수행되어 Handler 및 ModelAndView 개체에 대한 액세스를 제공합니다.
이렇게 하면 중복이 줄어들고 다음과 같은 더욱 세분화된 기능들에 대한 사용이 가능해 집니다:

  • 애플리케이션 로깅과 같은 교차 문제 처리
  • 자세한 인증 확인
  • Spring 컨텍스트 또는 모델 조작

5. 결론

이 글에서 우리는 Filter와 HandlerInterceptor의 차이점을 다루어 보았습니다.

이 글의 핵심은 필터를 사용하면 요청이 컨트롤러에 도달하기 전에 Spring MVC 외부에서 조작할 수 있다는 것입니다. 그렇지 않으면 HandlerInterceptors는 응용 프로그램별 교차 문제에 대한 훌륭한 장소입니다.

대상 Handler 및 ModelAndView 개체에 대한 액세스를 제공함으로써 보다 세밀하게 제어할 수 있습니다.

여기에서 사용한 전체 예제와 조각 코드의 구현은 GitHub에서 찾을 수 있습니다.

728x90