✅ Filter와 Interceptor는 Spring에서 요청을 가로채 처리할 수 있는 두 가지 주요 컴포넌트
✅ 두 컴포넌트 모두 요청(Request)과 응답(Response)에 대해 사전/사후 처리를 수행할 수 있지만, 동작 시점과 적용되는 범위가 다름
📌 Spring Filter
✅ WAS 레벨에서 동작
✅ DispatcherServlet 요청 전 실행
주요 메서드
public interface Filter {
void init(FilterConfig filterConfig) throws ServletException;
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
void destroy();
}🔹 doFilter()
- 모든 요청을 가로채어 특정 처리를 수행
- chain.doFilter(request, response)를 호출하지 않으면 요청이 DispatcherServlet으로 전달되지 않음
🔹 init()
- 필터가 처음 생성될 때 한 번만 실행되는 초기화 메서드
🔹 destroy()
- 필터가 제거될 때 한 번 실행되는 정리 작업 메서드
Filter & Bean
✅ Filter는 WAS에 의해 관리되는 서블릿 컴포넌트였기 때문에 Bean으로 등록할 수 없었음
✅ Filter에서도 Spring 기술을 필요로 하는 상황이 많아지면서 Bean으로 등록 가능해짐
🔹 DelegatingFilterProxy
✅ Spring Application Context의 Filter 클래스를 Servlet Filter에 등록할 수 있도록 해주는 객체
CustomFilter.java
@Component("loggingFilter")
public class CustomFilter implements Filter {
private static Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);
@Override
public void init(FilterConfig config) throws ServletException {
// initialize something
}
@Override
public void doFilter(
ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
LOGGER.info("Request Info : " + req);
chain.doFilter(request, response);
}
@Override
public void destroy() {
// cleanup code, if necessary
}
}ApplicationInitializer.java
public class ApplicationInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
// some other methods here
@Override
protected Filter[] getServletFilters() {
DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy();
delegateFilterProxy.setTargetBeanName("loggingFilter");
return new Filter[]{delegateFilterProxy};
}
}🔹 Spring Boot 등장
Spring Boot 등장 이후, Spring Boot가 내장 웹서버를 지원하면서 ServletContext를 직접 제어할 수 있기 때문에 위와 같은 과정 없이도 Filter 빈을 Filter Chain에 등록할 수 있게 되었다.
📌 Spring Interceptor
✅ Spring MVC에서 DispatcherServlet 이후, 컨트롤러로 요청이 가기 전후에 실행되는 컴포넌트
✅ Handler(Controller)를 실행하기 전/후에 특정 로직을 수행할 수 있도록 도움
필요한 상황
- API 요청 감사 또는 로깅
- 인증/인가 체크
- 요청 데이터 가공 컨트롤러 실행 전후에 필요한 공통 로직을 구현할 때 유용
주요 메서드
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, ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}🔹 preHandle()
요청을 가로채 컨트롤러 실행 전에 수행
🔹 postHandle()
컨트롤러 실행 후, View 렌더링 전에 작업 수행
🔹 afterCompletion()
요청 처리가 완료된 후 실행(예외가 발생하더라도 실행)
📌 참고
https://www.baeldung.com/spring-delegating-filter-proxy
https://mangkyu.tistory.com/221
https://www.baeldung.com/spring-mvc-handlerinterceptor
https://mangkyu.tistory.com/173