-
Filter, Interceptor🌱 spring 2022. 10. 11. 14:30
Spring은 공통적으로 여러 작업을 처리해 중복된 코드를 제거할 수 있도록 많은 기능을 지원한다.
- 필터(Filter) vs 인터셉터(Interceptor)
- 인터셉터와 AOP
📌 필터(Filter)
💡 필터(Filter)는 Dispatcher Servlet에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공한다.
Dispatcher Servelt은 스프링의 가장 앞단에 존재하는 프론트 컨트롤러이므로, 필터는 스프링 범위 밖에서 처리가 된다.
⇒ 일반적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 때 사용한다.
즉, 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리가 된다
- 스프링 빈으로 등록은 된다.
- 디스패처 서블릿 전 / 후에 처리
HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 처리한다.
- Request / Response에 대한 조작이 가능하다
- 유일하게 ServletRequest, ServletResponse 객체를 변환할 수 있다.
Spring Framework에서는 주로 request/response의 logging 용도로 활용하거나, 인증과 관련된 로직을 필터에서 처리한다.
필터의 메서드
필터를 추가하기 위해서는 javax.servlet의 Filter 인터페이스를 구현(implement)해야한다.
- init()
- doFilter()
- destroy()
public interface Filter { public default void init(FilterConfig filterConfig) throws ServletException {} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException; public default void destroy() {} }
init()
- 필터 객체를 초기화하고 서비스에 추가하기 위한 메소드 (웹 컨테이너가 호출)
- 이후 요청들은 doFilter를 통해 처리된다.
doFilter()
- url pattern에 맞는 모든 HTTP 요청이 dispatcher servlet으로 전달되기 전에 실행되는 메소드
- 필터의 파라미터인 FilterChain의 doFilter를 통해 다음 대상으로 요청을 전달하게 된다.
destroy()
- 필터 객체를 서비스에서 제거하고 사용하는 자원을 반환하기 위한 메소드
- 웹 컨테이너가 1번 호출하고 이후에는 doFilter에 의해 처리되지 않는다.
대표적으로 필터를 인증과 인가에 사용하는 도구로는 SpringSecurity가 있다.
- SpringSecurity의 특징 중 하나는 SpringMVC에 종속적이지 않다는 것.
- 이러한 이유로 필터 기반으로 인증/인가 처리를 한다.
📌 인터셉터 (Interceptor)
💡 인터셉터(Interceptor)는 필터와 달리 Spring이 제공하는 기술이다.
디스패처 서블릿이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공한다.즉, 인터셉터는 스프링 컨텍스트에서 동작을 한다.
Dispatcher Servlet은 내부적으로 핸들러 매핑을 통해 적절한 컨트롤러를 찾도록 요청한다.
- 이 결과로 실행 체인(HandlerExecutionChain)을 반환한다.
실행 체인은 스프링 컨테이너에 인터셉터가 등록되어 있다면 인터셉터들을 순차적으로 거친 후 컨트롤러를 실행하도록 한다.
인터셉터의 메소드
인터셉터를 추가하기 위해서는 org.springframework.web.servlet의 HandlerInterceptor 인터페이스를 구현(implements)해야 한다.
- preHandle()
- postHandle()
- afterCompletion()
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, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }
preHandle()
- 컨트롤러가 호출되기 전에 실행된다.
- 컨트롤러 이전에 처리해야 하는 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우 사용
- 반환 타입이 boolean이다
- true일시 다음 단계로 진행이 된다.
- false이면 작업을 중단하여 이후 작업이 진행되지 않는다.
postHandle()
- 컨트롤러가 호출된 후에 실행된다.
- 컨트롤러 이후에 처리해야 하는 후처리 작업이 있을 때 사용할 수 있다.
- 컨트롤러 하위 계층에서 예외가 발생하면 postHandle()은 호출되지 않는다.
afterCompletion()
- 모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행
- 요청 처리 중 사용한 리소스를 반환할 때 사용하기 적합하다.
- postHandle() 과 달리 컨트롤러 하위 계층에서 예외가 발생해도 반드시 호출된다.
🆚 필터 와 인터셉터의 차이 및 용도
필터와 인터셉터는 각각 관리되는 컨테이너와 Request / Response 조작가능 여부가 다르고 용도도 다르다.
대상 필터(Filter 인터셉터(Interceptor)
대상 필터(Filter) 인터셉터(Interceptor) 관리되는 컨테이너 웹 컨테이너 스프링 컨테이너 Request / Response
- 객체 조작 가능 여부O X 용도 - 공통된 보안 및 인증 / 인가 관련 작업
- 모든 요청에 대한 로깅 또는 검사
- 이미지 / 데이터 압축 및 문자열 인코딩
- Spring과 분리되어야 하는 기능- 세부적인 보안 및 인증 / 인가 관련 작업
- API 호출에 대한 로깅 또는 검사
- Controller로 넘겨주는 정보(데이터) 가공필터는 스프링 빈으로 등록 가능하고 다른곳에 주입되거나 다른 빈을 주입받을 수도 있다.
Request / Response 객체 조작 가능 여부
필터는 request와 response를 조작할 수 있지만 인터셉터는 조작할 수 없다.
조작
- 내부 상태를 변경 ❌
- 다른 객체로 바꿔친다는 의미
필터는 다른 필터를 호출하기 위해서 필터 체이닝을 해준다.
- 이때, request와 response 객체를 넘겨주는데
- 우리가 원하는 request, response 객체를 넣어줄 수 있다.
반면, 인터셉터는 필터와 다르다.
- 인터셉터는 true를 반환하면 다음 인터셉터가 실행되거나 컨트롤러로 요청이 전달되고,
- false를 반환하면 요청이 중단된다.
- 따라서, request, response 객체를 넘겨줄 수 없다.
용도
필터는 스프링과 무관하게 전역으로 처리해야 하는 작업들을 처리할 수 있다.
- 웹 애플리케이션에 전반적으로 사용되는 기능을 구현
- ServletRequest / ServletResponse 객체를 조작할 수 있다는 점에서 인터셉터보다 훨씬 강력하다.
인터셉터는 클라이언트의 요청과 관련되어 전역적으로 처리해야 하는 작업들을 처리할 수 있다.
- 인증이나 인가와 같이 클라이언트 요청과 관련된 작업등
- HttpServletRequest, HttpServletResponse 등과 같은 객체를 제공받으므로 객체 자체는 조작할 수 없다.
- 대신 객체 내부적으로 갖는 값을 조작할 수 있다.→ ex) 사용자의 정보를 HttpServletRequest에 넣어줄 수 있다.
- → 컨트롤러로 넘겨주기 위한 정보를 가공
참고 자료
https://mangkyu.tistory.com/173
https://velog.io/@lovi0714/필터Filter와-인터셉터Interceptor
https://velog.io/@miot2j/Spring-Filter-Interceptor-AOP-차이-및-AOP를-사용하여-Logging을-구현한-이유
https://velog.io/@ansalstmd/스프링부트-다양한-기능-5.-Spring-Boot-Filter와-Interceptor
'🌱 spring' 카테고리의 다른 글
JPA - Embedded Type (0) 2022.11.02 Spring Scheduler (0) 2022.10.24 OSIV 🧐 (0) 2022.10.11 JPA - N + 1 문제 (0) 2022.10.11 영속성 컨텍스트 (0) 2022.10.11