HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
[New] 타일러팀
[New] 타일러팀
/
🗄️
Filter Interceptor
🗄️

Filter Interceptor

공통 관심사 (cross-cutting concern)

  • 웹 개발시 공통적으로 처리해야 할 업무들이 많다.
    • 로그인 관련 (세션체크) 처리, 권한 체크
    • 로그
    • 페이지 인코딩 변환
    • XSS 방어
  • 공통업무에 관련된 코드를 모든 페이지 마다 작성된다면 중복된 코드의 증가하고 유지보수도 하기 힘들어진다.
  • 공통 관심사는 따로 관리하는것이 좋다.
notion image

Filter

  • 서블릿에서 지원해주는 기술.

Filter 흐름

💡
HTTP 요청 → WAS → 필터 → 서블릿(디스패처 서블릿) → 컨트롤러
필터를 적용하면 필터가 호출 된 다음에 서블릿이 호출된다.
모든 고객의 요청 로그를 남기는 요구사항이 있다면 필터를 사용하면된다.
(”/*” 설정시 모든 요청에 필터가 적용된다)

필터 제한

💡
HTTP 요청 → WAS → 필터 → 서블릿 → 컨트롤러 // 로그인 사용자 HTTP 요청 → WAS → 필터 (적절하지 않은 요청이라 판단, 서블릿 호출 X) // 비 로그인 사용자
  • 필터에서 적절하지 않은 요청이라고 판단하면 거기에서 끝을 낼 수도 있다. 그래서 로그인 여부를 체크하기에 좋다.

필터 체인

💡
HTTP 요청 → WAS → 필터1 → 필터2 → 필터3 → 서블릿 → 컨트롤러
필터는 체인으로 구성되는데, 중간에 필터를 자유롭게 추가할 수 있다.
Filter 인터페이스를 구현하고 등록하면 서블릿 컨테이너가 Filter를 싱글톤 객체로 생성하고, 관리한다.
  • init()
    • Filter 초기화 메서드, 서블릿 컨테이너가 생성될 때 호출된다.
  • doFilter()
    • 고객의 요청이 올 때 마다 해당 메서드가 호출된다. 필터의 로직을 구현하면 된다.
  • destroy()
    • Filter 종료 메서드, 서블릿 컨테이너가 종료될 때 호출된다.
 

2. Interceptor (인터셉터)

  • 서블릿 필터가 서블릿이 제공하는 기술이라면, 스프링 인터셉터는 스프링 MVC가 제공하는 기술
둘다 웹과 관련된 공통 관심 사항을 처리하지만, 적용되는 순서와 범위, 그리고 사용방법이 다르다.

Interceptor 흐름

💡
HTTP 요청 → WAS → 필터 → 서블릿(Dispatcher Servlet) → 스프링 인터셉터 → 컨트롤러
notion image
  • 스프링 인터셉터는 디스패처 서블릿과 컨트롤러 사이에서 컨트롤러 호출 직전에 호출된다.
  • 스프링 인터셉터에도 URL 패턴을 적용할 수 있는데, 서블릿 URL 패턴과는 다르고, 매우 정밀하게 설정할 수 있다.

Interceptor 제한

💡
HTTP 요청 → WAS → 필터 → 서블릿 → 스프링 인터셉터 → 컨트롤러 // 로그인 사용자 HTTP 요청 → WAS → 필터 → 서블릿 → 스프링 인터셉터(적절하지 않은 요청이라 판단, 컨트롤러 호출X) // 비 로그인 사용자
인터셉터에서 적절하지 않은 요청이라고 판단하면 거기에서 끝을 낼 수도 있다.
로그인 여부를 체크하기에 딱 좋다.

스프링 인터셉터 체인

💡
HTTP 요청 → WAS → 필터 → 서블릿 → 인터셉터1 → 인터셉터2 → 컨트롤러
  • 스프링 인터셉터는 체인으로 구성되는데, 중간에 인터셉터를 자유롭게 추가할 수 있다.
  • 예를 들어서 로그를 남기는 인터셉터를 먼저 적용하고, 그 다음에 로그인 여부를 체크하는 인터셉터를 만들 수 있다.

Interceptor 인터페이스

  • 서블릿 필터의 경우 단순하게 doFilter() 하나만 제공한다. 인터셉터는 컨트롤러 호출 전 (preHandle), 호출 후 (postHandle), 요청 완료 이후 (afterCompletion)와 같이 단계적으로 잘 세분화 되어 있다.
  • 서블릿 필터의 경우 단순히 request, response만 제공했지만, 인터셉터는 어떤 컨트롤러(handler)가 호출되는지 호출 정보도 받을 수 있다. 그리고 modelAndView 가 반환되는지 응답 정보도 받을 수 있다.

스프링 인터셉터 호출 흐름

notion image

정상 흐름

notion image
  • preHandle : 컨트롤러 호출 전에 호출된다. (더 정확히는 핸들러 어댑터 호출 전에 호출된다.
    • preHandle의 응답값이 true이면 다음으로 진행하고, false이면 더는 진행하지 않는다. false인 경우 나머지 인터셉터는 물롭이고, 핸들러 어댑터도 호출되지 않는다. 그림에서 1번에서 끝나버린다.
  • postHandle : 컨트롤러 호출 후에 호출된다. (더 정확히는 핸들러 어댑터 호출 후에 호출된다.)
  • afterCompletion : 뷰가 렌더링 된 이후에 호출된다.

스프링 인터셉터 예외 상황

notion image
예외 발생시
  • preHandle : 컨트롤러 호출 전에 호출된다.
  • postHandle : 컨트롤러에서 예외가 발생하면 postHandle은 호출되지 않는다.
  • afterCompetion : afterCompletion은 항상 호출된다. 이 경우 예외(ex)를 파라미터로 받아서 어떤 예외가 발생했는지 로그로 출력할 수 있다.
afterCompletion은 예외가 발생해도 호출된다.
  • 예외가 발생하면 postHandle()은 호출되지 않으므로 예외와 무관하게 공통 처리를 하려면 afterCompletion()을 사용해야 한다.
 

필터와 인터셉터의 용도 및 예시

필터

  • 공통된 보안 및 인증/인가 관련 작업
  • 모든 요청에 대한 로깅 또는 검사
  • 이미지/데이터 압출 및 문자열 인코딩
  • Spring과 분리되어야 하는 기능
스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 수 있다. 보안 공통 작업 ⇒ 전역적으로 해야하는 보안 검사 (XSS 방어)를 하여 올바른 요청이 아닐 경우 차단을 할 수 있다. 스프링 컨테이너까지 요청이 전달되지 못하고 차단되므로 안정성을 더욱 높일 수 있다.

인터셉터

  • 세부적인 보안 및 인증/인가 공통 작업
  • API 호출에 대한 로깅 또는 검사
  • Controller로 넘겨주는 정보 (데이터)의 가공
클라이언트의 요청과 관련되어 전역적으로 처리해야 하는 작업들을 처리할 수 있다.
 

정리

  • 인터셉터는 스프링 MVC 구조에 특화된 기능을 제공한다고 이해하면 된다. 스프링 MVC를 사용하고, 특별히 필터를 꼭 사용해야 하는 상황이 아니라면 인터셉터를 사용하는 것이 더 편리하다.
  • 인터셉터를 적용하거나 하지 않을 부분을 패턴을 사용해서 세밀하게 설정할 수 있다.
⇒ 이러한 이유로 인터셉터에서 많이 인증, 인가 코드를 구현하였다.
 
  • 대표적으로 필터를 인증과 인가에 사용하는 도구 : Spring Security
    • Spring MVC에 종속적이지 않다.
      • (스프링과 관련 없이 독립적으로 활동하던 프로젝트)
 
  • Filter, Interceptor에서 하는 것 그 중 어떤 것이 안전하냐 무의미
  • 체크 위치와 방법의 차이 ⇒ 고려해서 결정
 
Category
Spring
Created
May 22, 2022 08:51 AM
Person
State
완료
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() {} }
public interface HandlerInterceptor { // Controller 요청 전 default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } // Controller 요청 후 default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } // HTTP 요청이 완전히 끝날 때 default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }