public interface Filter {
default public void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException;
default public void destroy() {}
}
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 {
}
}
2-1) 컨트롤러는 타입과 실행 메소드가 모두 제각각이라 적용할 메소드 선별의 작성이 어렵다.
2-2) 컨트롤러는 파라미터나 리턴 값이 일정하지 않다.
인터셉터 대신에 컨트롤러들에 적용할 부가 기능을 어드바이스로 만들어 AOP를 적용할 수도 있다. 하지만 위와 같은 이유로 컨트롤러의 호출 과정에 적용되는 부가기능들을 인터셉터를 사용하는 편이 낫다.
즉, 타입이 일정하지 않고, 호출 패턴도 정해저있지 않기 때문에 컨트롤러에 AOP를 적용하려면 번거로운 부가 작업들이 생기게 된다.
- Filter는 기본적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 수 있다.
- Filter는 Interceptor보다 앞단에서 동작하기 때문에 보안 검사(XSS 방어 등)을 하여 올바른 요청이 아닌 경우 차단할 수 있다.
-> 스프링 컨테이너까지 요청이 전달되지 못하고 차단되기 때문에 안전성을 높일 수 있다.- Filter는 이미지나 데이터의 압축, 문자열 인코딩과 같이 웹 어플리케이션에 전반적으로 사용되는 기능을 구현하기에 적당하다.
- Interceptor에서 클라이언트의 요청과 관련되어 적역적으로 처리해야하는 작업들을 처리할 수 있다.
- 세부적으로 적용해야하는 인증이나 인가와 같이 특정 그룹의 사용자는 어떤 기능을 사용하지 못하는 경우에 해당 작업을 컨트롤러로 넘어가기 전에 검사해야 하므로 인터셉터가 처리하기에 적합하다.
- HttpServletRequest나 HttpServletResponse 등과 같은 제공받기 때문에 객체 자체를 조작할 수는 없다. 대신 해당 객체가 내주적으로 가지는 값은 조작할 수 있으므로 컨트롤러로 넘겨주기 위한 정보를 가공하기에 용이하다.
- 예시로 JWT 토큰 정보를 파싱해서 컨트롤러에게 사용자의 정보를 제공하도록 가공할 수 있다. 그 외에도 여러 목적으로 API 호출에 대한 정보를 기록해야하는 상황에 HttpServletRequest나 HttpServletResponse를 제공해주는 인터셉터는 클라이언트의 IP나 요청 정보들을 기록하기에 용이하다.