필터, 인터셉터 - Interceptor

김회민·2023년 2월 21일
0

Spring

목록 보기
18/25

Interceptor

HTTP 요청 → WAS(톰캣) → 필터 → 서블릿 (디스페처 서블릿) → 인터셉터 → 컨트롤러

인터셉터는 필터와 마찬가지로 클라이언트의 요청을 컨트롤러 호출 전에 처리하여 컨트롤러마다 동일한 로직을 처리 할 수 있게 지원해주는 기능이다.

필터는 서블릿에서 제공하는 기술인데 반해, 인터셉터는 스프링 MVC가 제공하는 기술이다.

인터셉터는 URL 패턴을 설정할 때 기존의 방식과는 다른, 스프링만의 방식(Path Pattern)을 사용한다.

인터셉터 또한 필터와 동일하게 체인 방식으로 여러 인터셉터를 순서대로 호출할 수 있도록 지원한다.

Interceptor 인터페이스

public interface HandlerInterceptor {
    /**
     * 컨트롤러 호출 전
     * false인 경우 나머지 인터셉터는 물론이고, 핸들러 어댑터도 호출되지 않는다.
     *
     * @return true = 다음으로 진행, false = 진행 멈춤.
     */
    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 { }
}

preHandle

  • 컨트롤러의 호출 전에 호출된다.
  • 반환값에 따라 다음으로 진행할지 안할지 정할 수 있다.
    • true: 다음 인터셉터로 진행
    • false: 바로 종료된다.
    • 인터셉터 1 PreHandle → 인터셉터 2 PreHandle false 반환 →
      더이상 진행 X → 인터셉터 1 afterComplete 호출 → 종료
  • handler 인자를 통해 어떤 컨트롤러가 호출되었는지 알 수 있다.
    • 정적 리소스: ResourceHttpRequestMethod
    • @RequestMapping: HandlerMethod
  • 인터셉터를 등록한 순서에 맞게 호출이 진행된다.
    • 디스페처 서블릿 → 인터셉터 1 → 인터셉터 2 → 인터셉터 3 → 컨트롤러

postHandle

  • 컨트롤러의 로직이 종료되면 호출된다.
  • modelAndView 인자를 통해 어떤 뷰 템플릿이 반환되었는지 알 수 있다.
  • 컨트롤러에서 예외가 발생한 경우 호출되지 않는다.
  • 인터셉터를 등록한 순서의 역방향으로 진행된다.
    • 컨트롤러 → 인터셉터 3 → 인터셉터 2 → 인터셉터 1 → 디스페처 서블릿

afterCompletion

  • 뷰 렌더링이 완료된 후 호출된다.
  • 컨트롤러에서 예외가 발생해도 호출된다.
    • ex 인자를 통해 어떤 예외가 발생했는지 확인할 수 있다.
  • 인터셉터를 등록한 순서의 역방향으로 진행된다.
    • 디스페처 서블릿 → 인터셉터 3 → 인터셉터 2 → 인터셉터 1 → 필터

인터셉터 등록

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor())
                .order(1)                                             // 우선 순위
                .addPathPatterns("/**")                               // 모두 허용
                .excludePathPatterns("/css/**", "/*.ico", "/error");  // BlackList
    }
}

WebMvcConfigurer의 addInterceptors를 오버라이드해서 registry 인자를 이용해 등록하면 된다.

  • registry.addInterceptor(new LogInterceptor())
    • 인터셉터를 구현한 구현체를 등록한다.
  • order(1)
    • 인터셉터의 순서를 지정한다.
  • addPathPatterns("/**")
    • 인터셉터가 호출될 URL을 지정한다.
    • 한 번에 여러 URL을 지정할 수 있다.
    • 해당 패턴은 PathPattern이라고 하는 것인데, 이는 다른 글에 소개해두었다.
  • excludePathPatterns("/css/**", "/*.ico", "/error")
    • 인터셉터가 호출하지 않을 URL을 지정한다.
    • 한 번에 여러 URL을 지정할 수 있다.
    • addPathPatterns에 등록한 URL보다 우선적으로 검사한다.

참고

profile
백엔드 개발자 지망생

0개의 댓글