목차
필터(Filter)
필터(Filter)는 J2EE 표준 스펙 기능으로 디스패처 서블릿(Dispatcher Servlet)에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공합니다.
디스패처 서블릿은 스프링의 가장 앞단에 존재하는 프론트 컨트롤이므로, 필터는 스프링 범위 밖에서 처러가 되는 것 이다.
즉, 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리가 되는 것이고 (스프링 빈으로 등록이 됩니다), 디스패처 서블릿 전/후에 처리하는 것입니다.
인터셉터(Interceptor)
인터셉터(Interceptor)는 J2EE 표준 스펙인 필터와 달리 Spring이 제공하는 기술로써, 디스패처 서브릿이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공합니다.
즉, 웹 컨테이너에서 동작하는 필터와 달리 인테셉터는 스프링 컨텍스트에서 동작합니다.
디스패처 서블릿은 핸들러 매핑을 통해 적절한 컨트롤러를 찾도록 요청하는데, 그 결과로 실행 체인(HandlerExecutionChain)을 돌려줍니다. 그래서 이 실행 체인은 1개 이상의 인터셉터가 등록되어 있다면 순차적으로 인터셉터들을 거쳐 컨트롤러가 실행되도록 하고, 인터셉터가 없다면 바로 컨트롤러를 실행합니다.
인터셉터는 스프링 컨테이너 내에서 동작하므로 필터를 거쳐 프론트 컨트롤러인 디스패처 서블릿이 요청을 받은 이후에 동작하게 되는데, 이러한 호출 순서를 그림으로 표현하면 다음과 같습니다.
필터(Filter) 와 인터셉터(Interceptor) 용도 및 차이
필터(Filter)의 용도 및 예시
- 공통된 보안 및 인증/인가 관련 작업
- 모든 요청에 대한 로깅 또는 검사
- 이미지/데이터 압축 및 문자열 인코딩
- Spring과 분리되어야 하는 기능
필터에서는 기본적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 수 있습니다.
대표적으로는 보안 공통 작업이 있습니다. 필터는 인터셉터보다 앞단에서 동작하므로 전역적으로 해야하는 보안 검사(XSS 방어 등)을 하여 올바른 요청이 아닐 경우 차단할 수 있습니다. 그러면 스프링 컨테이너까지 요청이 전달되지 못하고 차단되므로 안정성을 더욱 높일 수 있습니다.
또한 필터는 이미지나 데이터의 압축이나 문자열 인코딩과 같이 웹 에플리케이션에 전반적으로 사용되는 기능을 구현하기에 적당합니다. 필터는 다음 체인으로 넘기는 ServletRequest / ServletResponse 객체를 조작할 수 있다는 점에서 인터셉터보다 더 강력한 기술입니다.
대표적으로 필터(Filter)를 인증과 인가에 사용하는 도구로는 SpringSecurity가 있따. SperingSecurity의 특징 중 하나는 Spring MVC에 종속적이지 않다는 것 입니다. 이러한 이유로 필터 기반으로 인증 / 인가 처리를 합니다.
인터셉터(Interceptor)의 용도 및 예시
- 세부적인 보안 및 인증 / 인가 공통 작업
- API 호출에 대한 로깅 또는 감사
- Controller로 넘겨주는 정보(데이터)의 가공
인터셉터에서는 클라이언트의 요청과 관련되어 전역적으로 처리해야 하는 작업들을 처리할 수 있습니다.
대표적으로 세부적으로 적용해야 하는 인증이나 인가와 같이 클라이언트 요청과 관련된 작업 등이 있습니다. 예를 들어 특정 그룹의 사용자는 어떤 기능을 사용하지 못하는 경우가 있는데, 이러한 작업들은 컨트롤러로 넘어가기 전에 검사해야 하므로 인터셉터가 처리하기에 적합합니다.
또한 인터셉테는 필터와 다르게 HttpServletRequest 나 HttpServletResponse 등과 같은 객체를 제공받으므로 객체 자체를 조작할 수는 없습니다. 대신 해당 객체가 내부적으로 갖는 값은 조작할 수 있으므로 컨트롤러로 넘겨주기 위한 정보를 가공하기에 용이합니다. 예를 들어 JWT 토큰 정보를 파싱해서 컨트롤러에게 사용자의 정보를 제공하도록 가공할 수 있습니다. 그 외에도 우리는 다양한 목적으로 API 호출에 대한 정보들을 기록해야 합니다. 이러한 경우에 HttpServletRequest나 HttpServletResponse를 제공해주는 인터셉터는 클라이언트의 IP나 요청 정보들을 포함해 기록하기에 용이합니다.
필터(Filter) 와 인터셉터(Interceptor) 차이
필터와 인터셉터는 각각 관리되는 컨테이너와 Request / Response 의 조작가능 여부가 다르고, 그에 따라 용도가 다릅니다.
Request / Response 객체 조작 가능 여부
필터는 Request와 Response를 조작할 수 있지만 인터셉터는 조작할 수 없습니다. 여기서 조작한다는 것은 내부 상태를 변경한다는 것이 아니라 다른 객체로 바꿀 수 있다는 의미입니다.
이는 필터와 인터셉터의 코드를 보면 알 수 있습니다. 필터가 다음 필터를 호출하기 위해서는 필터 체이닝(다음 필터 호출)을 해주어야 합니다. 그리고 이 때 Request / Response 객체를 넘겨주므로 우리가 원하는 Request / Response 객체를 넣어 줄 수 있습니다.
public MyFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
// 개발자가 다른 request와 response를 넣어줄 수 있음
chain.doFilter(request, response);
}
}
하지만 인터셉터는 처리 과정이 필터와는 다릅니다. 디스패처 서블릿이 여러 인터셉터 목록을 가지고 있고, for 문으로 순차적으로 실행시킵니다. 그리고 true를 반환하면 다음 인터셉터가 실행되거나 컨트롤러로 요청이 전달되며, false가 반환되면 요청이 중단됩니다. 그러므로 우리가 다른 Request / Response 객체를 넘겨줄 수 있습니다.
public class MyInterceptor implements HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// Request/Response를 교체할 수 없고 boolean 값만 반환할 수 있다.
return true;
}
}
참조
https://mangkyu.tistory.com/173
[Spring] 필터(Filter) vs 인터셉터(Interceptor) 차이 및 용도 - (1)
Spring은 공통적으로 여러 작업을 처리함으로써 중복된 코드를 제거할 수 있도록 많은 기능들을 지원하고 있다. 이번에는 그 중에서 필터(Filter) vs 인터셉터(Interceptor)의 차이에 대해 알아보고자
mangkyu.tistory.com