필터와 인터셉터의 차이 그리고 로깅
업데이트:
필터란?
필터는 Java Servlet 스펙의 일부로, 웹 애플리케이션의 요청-응답 처리 사이클에서 작동합니다. 클라이언트의 요청이 서블릿에 도달하기 전과 서블릿의 응답이 클라이언트에게 반환되기 전에 동작합니다.
필터의 주요 특징
① 광범위한 적용 범위
모든 서블릿 기반 웹 애플리케이션에 적용 가능합니다.
② 체인 구조 지원
여러 개의 필터를 체인 구조로 연결하여 사용할 수 있습니다.
③ URL 패턴 지원
특정 URL 패턴에 대해서만 필터를 적용할 수 있습니다.
주요 메서드
-
init(FilterConfig config):
필터 초기화 -
doFilter(ServletRequest request, ServletResponse response, FilterChain chain):
실제 필터링 로직 -
destroy():
필터 종료 시 호출
필터의 사용 예시
public class LoggingFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Request received");
chain.doFilter(request, response);
System.out.println("Response sent");
}
// init() 및 destroy() 메서드 구현...
}
주요 용도
-
인증 및 권한 검사
-
인코딩 변환
-
로깅 및 감사
-
요청/응답 데이터 변환 및 압축
2. 인터셉터란?
인터셉터는 Spring MVC 프레임워크에서 제공하는 기능으로, 컨트롤러의 호출 전후에 동작합니다. DispatcherServlet과 컨트롤러 사이에서 요청과 응답을 가로챕니다.
인터셉터의 주요 특징
① spring 전용
Spring MVC 프레임워크에서만 사용 가능합니다.
② 세밀한 제어
특정 컨트롤러나 핸들러 메서드에 대해 선택적으로 적용 가능합니다.
③ Spring Bean 활용 가능
다른 Spring Bean을 주입받아 사용할 수 있습니다.
④ AOP와 유사
메서드 실행 전후에 로직을 삽입할 수 있어 AOP와 유사한 기능을 제공합니다.
인터셉터의 주요 메서드
-
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):
컨트롤러 실행 전 -
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):
컨트롤러 실행 후, 뷰 렌더링 전 -
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex):
뷰 렌더링 후
인터셉터의 사용 예시
public class PerformanceInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
long startTime = (Long) request.getAttribute("startTime");
long endTime = System.currentTimeMillis();
System.out.println("Request processing time: " + (endTime - startTime) + "ms");
}
// afterCompletion() 메서드 구현...
}
주요 용도
-
세부적인 권한 검사
-
트랜잭션 처리
-
로깅 및 모니터링
-
컨트롤러 실행 시간 측정
필터 vs 인터셉터 📌
필터(Filter) 는 특정 요청과 컨트롤러에 관계없이 전역적으로 처리해야 하는 작업이나 웹 어플리케이션에 전반적으로 사용되는 기능을 구현할 때 적용하고,
인터셉터(Interceptor) 는 클라이언트의 요청과 관련된 작업에 대해 추가적인 요구사항을 만족해야 할 때 적용한다.
Spring MVC 통합:
인터셉터: HandlerMethod( Spring MVC에서 HTTP 요청을 처리하는 컨트롤러 메서드에 대한 메타데이터를 나타내는 클래스)를 사용하여 컨트롤러의 메서드 정보를 로깅할 수 있습니다. 이는 Spring MVC의 특정 기능입니다.
필터: 필터에서는 HandlerMethod에 접근할 수 없습니다. 필터는 서블릿 수준에서 동작하기 때문입니다.
실행 시점:
인터셉터: preHandle, postHandle, afterCompletion 메서드를 통해 요청 처리의 여러 단계에 개입할 수 있습니다.
필터: doFilter 메서드 하나만 있어, 요청 전후로만 로직을 추가할 수 있습니다.
예외 처리:
인터셉터: afterCompletion 메서드에서 예외 정보를 받아 처리할 수 있습니다.
필터: 예외 정보를 직접 받지 못하며, try-catch로 감싸서 처리해야 합니다.
ModelAndView 접근:
인터셉터: postHandle 메서드에서 ModelAndView에 접근할 수 있습니다.
필터: ModelAndView에 접근할 수 없습니다.
면접을 봤을때 왜 필터가 아닌 인터셉터를 사용하셨냐고 물어보면 뭐라고 대답하는게 좋을까?
Spring MVC와의 통합: 우리 프로젝트는 Spring MVC 기반으로 구축되어 있습니다. 인터셉터는 Spring MVC의 일부로, HandlerMethod를 통해 컨트롤러와 메서드에 대한 더 상세한 정보에 접근할 수 있습니다. 이를 통해 로깅, 보안 검사 등을 더 세밀하게 구현할 수 있었습니다.
요청 처리 생명주기: 인터셉터는 preHandle, postHandle, afterCompletion 메서드를 제공하여 요청 처리의 여러 단계에 개입할 수 있습니다. 이를 통해 요청 처리 전, 후, 그리고 뷰 렌더링 후에 각각 다른 로직을 적용할 수 있어 더 유연한 처리가 가능했습니다.
예외 처리: afterCompletion 메서드에서 예외 정보를 직접 받아 처리할 수 있어, 예외 상황에 대한 로깅이나 추가적인 처리를 더 쉽게 구현할 수 있었습니다.
Spring 기능 활용: 인터셉터는 Spring의 다른 기능들(예: 의존성 주입)을 쉽게 활용할 수 있어, 더 복잡한 비즈니스 로직을 인터셉터 내에서 구현할 수 있었습니다.
성능: 필터는 모든 요청에 대해 동작하지만, 인터셉터는 DispatcherServlet이 처리하는 요청에 대해서만 동작합니다. 이는 불필요한 처리를 줄여 성능 향상에 도움이 됩니다.
반대로 왜 인터셉터가 아닌 필터를 선택했냐는 질문을 받았을때에는 어떻게 대답하는게 좋을까?
광범위한 적용 범위: 필터는 서블릿 컨테이너 수준에서 작동하기 때문에, Spring의 DispatcherServlet에 도달하기 전에 모든 요청을 처리할 수 있습니다. 우리 프로젝트는 Spring MVC 뿐만 아니라 다른 서블릿 기반 요소들도 포함하고 있어, 모든 요청에 대해 일관된 처리가 필요했습니다.
프레임워크 독립성: 필터는 서블릿 스펙의 일부이므로, Spring 프레임워크에 의존하지 않습니다. 이는 향후 프레임워크 변경이나 마이그레이션 시에도 현재의 로직을 그대로 사용할 수 있다는 장점이 있습니다.
요청/응답 객체 변형: 우리 프로젝트에서는 요청이나 응답 객체를 수정해야 하는 경우가 있었습니다. 예를 들어, 멀티파트 요청의 파싱이나 응답 압축 등의 작업은 필터에서 더 적절하게 처리할 수 있었습니다.
보안 관련 처리: 인증이나 로깅과 같은 보안 관련 작업은 애플리케이션 로직이 실행되기 전에 처리되어야 합니다. 필터는 이러한 요구사항을 만족시키는 데 적합했습니다.
성능 고려: 일부 처리는 Spring 컨텍스트가 로드되기 전에 수행되어야 했습니다. 필터를 사용함으로써 불필요한 처리를 줄이고 전반적인 요청 처리 속도를 개선할 수 있었습니다.
서드파티 라이브러리 통합: 우리가 사용하는 일부 서드파티 보안 라이브러리들이 필터 기반으로 동작하기 때문에, 이들과의 일관성을 위해 필터를 선택했습니다.
참고사이트
https://mozzi-devlog.tistory.com/9
https://velog.io/@uiurihappy/Spring-%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0Interceptor%EC%99%80-%ED%95%84%ED%84%B0Filter-%EC%B0%A8%EC%9D%B4
댓글남기기