[Spring] Filter 와 Interceptor

김민범·2024년 11월 18일

Spring

목록 보기
21/29

Spring에서 FilterInterceptor는 HTTP 요청을 가로채고 처리하는 데 사용되지만, 그 동작 방식과 적용 범위에서 몇 가지 차이가 있다.


1. Filter

FilterServlet API의 일부이며, 요청과 응답을 변환하거나 가로채는 데 사용된다. Spring에서도 Servlet 필터를 지원한다.

특징

  • 기본 동작:
    • HTTP 요청/응답을 변환하거나 처리.
    • 주로 요청의 전처리 및 응답의 후처리에 사용됨.
    • 요청/응답 본문, 헤더, 파라미터 등을 수정하거나, 인증/인가를 처리할 수 있음.
  • 작동 시점:
    • DispatcherServlet(스프링의 핵심 서블릿)이 실행되기 이전/이후에 동작.
  • 기술적 위치:
    • 필터는 서블릿 컨테이너 레벨에서 동작하므로, 스프링 컨트롤러나 다른 스프링 구성 요소를 알 필요가 없음.
  • 등록 방식:
    • @WebFilter 어노테이션.
    • 또는 FilterRegistrationBean을 사용하여 Spring Bean으로 등록.

예시

@Component
public class CustomFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        System.out.println("CustomFilter: Request URI is " + httpRequest.getRequestURI());

        // 요청 처리 후 다음 필터로 전달
        chain.doFilter(request, response);

        // 응답 처리
        System.out.println("CustomFilter: Response completed");
    }
}

2. Interceptor

Interceptor는 Spring MVC의 HandlerInterceptor 인터페이스를 구현한 클래스이다. 주로 컨트롤러 로직 전후를 제어할 때 사용된다.

특징

  • 기본 동작:
    • 핸들러(컨트롤러) 호출 전후의 동작을 제어.
    • 요청 로깅, 인증/인가 처리, 공통 작업 수행 등 주로 애플리케이션 로직 레벨에서 사용.
  • 작동 시점:
    • DispatcherServlet이 핸들러(컨트롤러)를 호출하기 전후에 동작.
    • View가 렌더링되기 전에도 동작 가능.
  • 기술적 위치:
    • Interceptor는 Spring MVC와 연관되어 있으며, 핸들러나 뷰와 밀접하게 연결됨.
  • 등록 방식:
    • Spring의 WebMvcConfigurer를 통해 등록.

예시

@Component
public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("CustomInterceptor: Before Controller");
        return true; // true: 다음 단계 진행, false: 요청 처리 중단
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) {
        System.out.println("CustomInterceptor: After Controller but before View");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("CustomInterceptor: After View Rendered");
    }
}

3. 주요 차이점 비교

구분FilterInterceptor
레벨Servlet 레벨에서 동작Spring MVC 레벨에서 동작
사용 목적요청/응답 전반적인 처리 (헤더, 본문 등)핸들러(컨트롤러) 호출 전후 제어
작동 시점DispatcherServlet 전후DispatcherServlet 이후
구현 인터페이스javax.servlet.FilterHandlerInterceptor
주요 용도인증/인가, 요청 변환, 로깅컨트롤러 전/후 공통 로직 처리
Spring 의존성Spring에 의존하지 않음Spring MVC와 밀접히 연관
등록 방법@WebFilter 또는 FilterRegistrationBeanWebMvcConfigurer를 통한 등록

4. 함께 사용할 경우

Filter와 Interceptor는 함께 사용할 수 있다. 이 경우 Filter가 먼저 실행되고, 그다음 Interceptor가 실행된다.
필터는 더 범용적이고, 인터셉터는 더 구체적으로 Spring MVC 로직을 다룬다는 점에서 차이가 있다.

  • Filter: HTTP 수준의 보안, 요청/응답 데이터 수정.
  • Interceptor: 비즈니스 로직에 가까운 인증/인가, 공통 처리.

왜 필터와 인터셉터를 구분하는가?

필터와 인터셉터는 역할과 책임이 명확히 구분되기 때문에 둘 중 하나만 사용하기보다 각자의 특성을 살려 적합한 경우에 사용하는 것이 더 효과적이다. 인터셉터로 대부분의 로직을 처리할 수 있을 것 같아 보이지만, 필터가 필요한 경우도 많다. 다음은 필터와 인터셉터를 따로 사용하는 이유를 설명한다.

1. 필터는 HTTP 요청/응답의 전처리와 후처리를 책임

  • 필터는 DispatcherServlet 이전 단계에서 동작하며, Spring 컨텍스트나 MVC 구조에 종속되지 않음.
  • 주로 HTTP 요청/응답 데이터를 직접 다룰 필요가 있는 경우 사용함.
    • 예: 요청 본문이나 응답 본문(Content)을 읽거나 변환.
    • 예: CORS 처리, GZIP 압축, 캐싱 설정 등.
  • 인터셉터는 이런 역할을 할 수 없음.
    • 인터셉터는 DispatcherServlet 이후에 동작하므로, HTTP 요청/응답 본문(body)을 수정하거나 처리하기 어렵다.

2. 인터셉터는 Spring MVC에 특화된 로직 처리

  • 인터셉터는 Spring MVC의 컨트롤러와 View 단계에 밀접하게 연결됨.
    • 컨트롤러 실행 전/후에 공통 로직을 넣는 데 적합.
    • 인증/인가, 로깅, 컨트롤러 호출 전 데이터 설정 등에 사용.
  • HTTP 레벨의 로직(CORS, 헤더 변환 등)은 MVC와 관련이 없으므로, 인터셉터로 처리하기에 적합하지 않음.

3. 기술적 차이에 의한 사용 제한

  • 필터는 Servlet API를 기반으로 동작하여, Spring에 의존하지 않아도 작동 가능.
    • Spring 외의 서블릿 기반 애플리케이션에서도 사용 가능.
  • 반면, 인터셉터는 Spring MVC에 종속적이기 때문에 Spring Context를 벗어난 요청에는 동작하지 않음.

4. 성능 및 효율성 측면

  • 필터는 Spring MVC 레이어를 거치지 않고 더 하위 레벨에서 동작하므로 성능 최적화가 필요한 경우 더 적합.
  • 불필요한 Spring Context 초기화나 DispatcherServlet 호출을 줄일 수 있음.
    • 예: 정적 리소스 처리.

5. 실제 사용 사례 비교

필터로 적합한 작업

  1. CORS 처리: 브라우저에서의 교차 출처 요청을 허용/제한.
  2. HTTP 요청/응답 로깅: 요청의 헤더, 본문, 응답 등을 기록.
  3. GZIP 압축: 응답 본문을 압축하여 클라이언트로 전송.
  4. 보안 처리: XSS, SQL Injection과 같은 보안 위협 차단.

인터셉터로 적합한 작업

  1. 사용자 인증/인가: 세션이나 JWT 토큰을 검증하여 요청 차단.
  2. 로깅: 컨트롤러 호출 전후의 데이터를 기록.
  3. 공통 데이터 설정: 컨트롤러에 전달할 공통 속성 추가.
  4. Post-Processing: View 렌더링 전 데이터 가공.

결론

왜 둘을 따로 사용하는가?

  • 필터는 HTTP 요청/응답의 전반적인 처리를 담당하며, Spring 컨텍스트와 무관하게 동작해야 할 때 적합하다.
  • 인터셉터는 Spring MVC의 컨트롤러 단계와 밀접한 비즈니스 로직이나 공통 처리를 위해 설계되었다.

이 두 가지를 분리함으로써 역할이 명확해지고, 시스템 설계가 더 유연하며 유지보수도 쉬워진다.
필터를 사용하지 않고 인터셉터만으로 모든 로직을 처리하려 하면 HTTP 레벨의 세부 작업을 처리할 수 없어 한계에 봉착할 수 있다.

0개의 댓글