간단 요약
Filter | Interceptor | |
관리되는 컨테이너 | 웹 컨테이너 | 스프링 컨테이너 |
Request/Response 객체 조작 가능 여부 | O | X |
용도 | * 공통된 보안 및 인증/인가 관련 작업 * 모든 요청에 대한 로깅 또는 감사 * 이미지/데이터 압축 및 문자열 인코딩 * Spring 과 분리되어야 하는 기능 |
* 세부적인 보안 및 인증/인가 공통 작업 * API 호출에 대한 로깅 또는 감사 * Controller 로 넘겨주는 정보(데이터)의 가공 |
Servlet Filter
필터는 말 그대로 요청과 응답을 거른 뒤 정제하는 역할을 한다.
- 자바에서 제공
- Dispatcher Servlet에 요청이 전달되기 전/후에 URL 패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공
- Dispatcher Servlet은 스프링 가장 앞단에 있는 프론트 컨트롤러이기 때문에, 필터는 스프링 범위 밖에서 처리된다.
- 필터는 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리된다. (그러나 필터도 스프링 빈으로 등록이 됨)
Filter 인터페이스
public interface Filter {
public default void init(FilterConfig filterConfig) throws ServletException {
// 필터 객체 초기화
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
// 필터 처리 구현
// FilterChain 파라미터를 사용하여 다음 필터로 요청을 넘길 수 있다.
public default void destroy() {
// 필터 객체를 제거하고 사용하는 자원을 반환하기 위한 메소드
}
}
Spring Interceptor
요청에 대한 작업 전/후로 가로챈다고 보면 된다.
- 스프링이 제공하는 기술
- 정식 명칭은 Handler Interceptor
- Dispatcher Servlet이 컨트롤러를 호출하기 전/후(정확하게는 HandlerAdapter에서)에 인터셉터가 끼어들어 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공
- 스프링 컨텍스트에서 동작
Dispatcher Servelt은 핸들러 매핑을 통해 들어온 요청에 대한 적절한 컨트롤러를 찾는다.
그 결과로 실행 체인 (HandlerExecutionChain)을 돌려받게 된다.
만약 HandlerExecutionChain이 1개 이상의 인터셉터가 등록되어 있다면 순차적으로 등록된 인터셉터들을 거친 후 컨트롤러가 실행 된다.
인터셉터가 없다면 바로 컨트롤러를 실행한다.
HandlerInterceptor 인터페이스
public interface HandlerInterceptor
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 반환 타입이 boolean
// true 일 경우 계속 진행
// false일 경우 진행 멈춤
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 {
// 요청이 완료된 후 실행 (뷰가 렌더링 된 후에 실행)
}
}
차이점
- 호출되는 시점
- 파란색 막대가 필터가 호출되는 시점, 초록색 막대가 인터셉터가 호출되는 시점
⇒ 가장 눈에 띄는 차이점은 이 두 가지가 호출되는 시점이 다르다는 점.
- 관리되는 컨테이너
- 필터는 자바에서 제공하는 기능
- 인터셉터는 스프링 프레임워크에서 제공하는 기능
- Request/Response 객체 조작 가능 여부
- 필터는 Request 와 Response를 조작할 수 있지만 Interceptor는 조작할 수 없다.
# Filter
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 다른 request와 response를 넣어줄 수 있다
chain.doFilter(request, response);
}
}
필터가 다음 필터를 호출하기 위해 필터 체이닝(다음 필터를 호출)을 해줘야한다.
이때 request, response 객체를 넘겨주므로 우리가 원하는 request, response 객체를 넣어줄 수 있다.
# Interceptor
public class MyInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Request, Response를 교체할 수 없고 boolean 값만 반환 가능하다
return true;
}
}
디스패처 서블릿이 여러 인터셉터 목록을 가지고 있고, 순차적으로 실행시킨다.
그리고 true를 반환하면 다음 인터셉터가 실행되거나 컨트롤러로 요청이 전달되며, false가 반환되면 요청이 중단된다.
그러므로 다른 request, response 객체를 넘겨줄 수 없다.
- 필터와 인터셉터의 용도 및 예시
# 필터의 사용 사례
필터는 기본적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 수 있다.
- 보안 및 인증/인가 관련 작업
- 모든 요청에 대한 로깅 또는 검사
- 이미지/데이터 압축 및 문자열 인코딩
- 스프링과 분리되어야 하는 기능
필터는 인터셉터보다 앞단에서 동작하기 때문에 보안 검사(XSS 방어 등)를 하여 올바른 요청이 아닐 경우 차단할 수 있다.
그럼 스프링 컨테이너까지 요청이 전달되지 못 하고 차단되므로 안정성을 높일 수 있다.
또한, 필터는 이미지나 데이터의 압축, 문자열 인코딩과 같이 웹 어플리케이션에 전반적으로 사용되는 기능을 구현하기에 적당하다.
# 인터셉터의 사용 사례
인터셉터에서는 클라이언트의 요청과 관련되어 처리해야 하는 작업들을 처리할 수 있다.
- 세부적인 보안 및 인증/인가 공통 작업
- 클라이언트 요청과 관련된 인증, 인가 작업
- 예시) 특정 그룹의 사용자에 대한 기능 제한 등
- API 호출에 대한 로깅 또는 검사
- 컨트롤러로 넘겨주는 정보(데이터)의 가공
인터셉터는 필터와 다르게 HttpServletRequest나 HttpServletResponse 등과 같은 객체를 제공받으므로 객체 자체를 조작할 수는 없다.
대신 해당 객체가 내부적으로 갖는 값은 조작할 수 있으므로 컨트롤러로 넘겨주기 위한 정보를 가공하기에 용이하다.
필터(Filter)는 특정 요청과 컨트롤러에 관계없이 전역적으로 처리해야 하는 작업이나 웹 어플리케이션에 전반적으로 사용되는 기능을 구현할 때 적용하고, 인터셉터(Interceptor)는 클라이언트의 요청과 관련된 작업에 대해 추가적인 요구사항을 만족해야 할 때 적용한다.
+ 참고한 블로그 및 영상
https://algopoolja.tistory.com/110
'스터디 > 성희' 카테고리의 다른 글
IoC 컨테이너의 개념 및 역할 (0) | 2024.04.24 |
---|---|
BufferedReader, BufferedWriter (1) | 2024.04.08 |