[Spring] Filter, interceptor

Servlet Filter, Spring Interceptor

Servlet Filter

필터 흐름

  • HTTP 요청 → WAS → 필터 → 서블릿 → 컨트롤러
  • 필터를 적용하면 필터가 호출된 다음에 서블릿이 호출된다.
    • 모든 고객의 요청 로그를 남기는 요구사항 : 필터 적용
  • 스프링을 사용하는 경우 서블릿은 DispatcherServlet 으로 생각하면 된다

필터 제한

  • 로그인 사용자 : HTTP 요청 → WAS → 필터 → 서블릿 → 컨트롤러
  • 로그인 X 사용자 : HTTP 요청 → WAS → 필터(적절하지 않은 요청이라 판단, 서블릿 호출 X)
  • 필터에서 적절하지 않은 요청이라고 판단하면 여기서 끝낼 수도 있음

필터 체인

  • HTTP 요청 → WAS → 필터1 → 필터2 → 필터3 → 서블릿 → 컨트롤러
  • 중간에 필터를 자유롭게 추가 가능.
  • 예시) 로그 남기는 필터 -> 로그인 여부 체크 필터

필터 인터페이스

  • init() : 필터 초기화 메서드. 서블릿 컨테이너가 생성될 때 호출됨
  • doFilter() : 요청이 올 때마다 해당 메서드가 호출됨. 필터의 로직 부분
  • destroy() : 필터 종료 메서드. 서블릿 컨테이너 종료될 때 호출됨
  • 싱글톤으로 작동됨

Spring Interceptor

스프링 인터셉터 흐름

  • HTTP 요청 → WAS → 필터 → 서블릿 → 스프링 인터셉터 → 컨트롤러
  • 스프링 인터셉터는 디스패처 서블릿과 컨트롤러 사이에서 컨트롤러 호출 직전에 호출된다
  • 스프링 MVC가 제공하는 기능이기 때문에 결국 디스패처 서블릿 이후 등장.
  • 스프링 인터셉터에도 URL 패턴을 적용할 수 있다. 서블릿 URL 패턴과는 매우 다르고, 더 정밀하게 설정 가능.

스프링 인터셉터 제한

  • 로그인 사용자 : HTTP 요청 → WAS → 필터 → 서블릿 → 스프링 인터셉터 → 컨트롤러
  • 로그인 X 사용자 : HTTP 요청 → WAS → 필터 → 서블릿 → 스프링 인터셉터(적절하지 않은 요청이라 판단, 컨트롤러 호출 X)

스프링 인터셉터 체인

  • HTTP 요청 → WAS → 필터 → 서블릿 → 스프링 인터셉터1 → 스프링 인터셉터2 → 스프링 인터셉터3 → 컨트롤러

스프링 인터셉터 인터페이스

  • HandlerInterceptor 인터페이스를 구현하면 된다
  • 서블릿 필터의 경우 단순하게 doFilter() 하나만 제공됨.
  • 인터셉터는 컨트롤러 호출 전 preHandle() , 호출 후 postHandle(), 요청 완료 이후 afterCompletion() 과 같이 단계 세분화되어 있음
  • 서블릿 필터는 request, response 만 제공. 인터셉터는 어떤 컨트롤러(handler)가 호출되는지 호출 정보도 받을 수 있음. 그리고 어떤 modelAndView 가 반환되는지 응답 정보도 받을 수 있음

스프링 인터셉터 호출 흐름

interceptor

  • preHandle : 핸들러 어댑터 호출 전에 호출됨
    • preHandle의 응답값이 true 이면 다음으로 진행하고, false 이면 더는 진행하지 않는다. false인 경우 나머지 인터셉터는 물론이고, 핸들러 어댑터도 호출되지 않는다.
  • postHandle : 핸들러 어댑터 호출 후에 호출됨
    • 예외 발생 시 postHandle 이 호출되지 않는다.
  • afterCompletion : 뷰가 렌더링 된 이후에 호출
    • postHandle과 달리 예외가 발생해도 호출됨

정리

특별히 필터를 꼭 사용해야 하는 상황이 아니라면 인터셉터를 사용하는 것이 더 편리하다.

참조