본문 바로가기
[ JAVA ]/JAVA Spring

[ Spring ] Spring Interceptor - 소개

by 환이s 2024. 1. 9.
728x90


 

Spring Interceptor는 Servlet Filter와 같이 WEB과 관련된 공통 관심 사항을 효과적으로 해결할 수 있는 기술입니다.

 

Servlet Filter가 Servlet이 제공하는 기술이라면, Spring Interceptor는 SpringMVC가 제공하는 기술입니다.

둘 다 WEB과 관련된 공통 관심 사항을 처리하지만, 적용되는 순서와 범위, 그리고 사용방법이 다릅니다.

 

오늘은 SpringMVC가 제공하는 Interceptor에 대해 알아보겠습니다.


 

Spring Interceptor 흐름

 

Spring Interceptor의 흐름에 대해 먼저 알고 넘어가자면 다음과 같습니다.

 

HTTP 요청 -> WAS -> Filter -> Servlet -> Spring Interceptor -> Controller 

 

 

Spring Interceptor는 디스패처 서블릿과 컨트롤러 사이에서 컨트롤러 호출 직전에 호출됩니다.

 

SpringMVC가 제공하는 기능이기 때문에 결국 디스패처 서블릿 이후에 등장하게 되는데,

SpringMVC의 시작점이 디스패처 서블릿이라고 생각해 보면 될 거 같습니다.

 

또한 Spring Interceptor에도 URL Pattern을 적용할 수 있는데, Servlet URL Pattern과는 다르고, 

매우 정밀하게 설정할 수 있습니다.

 

[ 제한 ]

HTTP -> WAS -> FILTER -> SERVLET -> SPRING INTERCEPTOR -> CONTROLLER  //LOGIN USER

HTTP -> WAS -> FILTER -> SERVLET -> SPRING INTERCEPTOR(LOGIN USER NOT ? CONTROLLER URL ="X")  // LOGIN NOT USER

 

Interceptor에서 적정하지 않은 요청이라고 판단하면 거기에서 끝을 낼 수도 있습니다.

그래서 로그인 여부를 체크하기에 딱 좋습니다.

 

[ 인터셉터 체인 ]

HTTP -> WAS -> FILTER -> SERVLET -> INTERCEPTOR 1 -> INTERCEPTOR 2 -> CONTROLLER 

 

Spring Interceptor는 체인으로 구성되는데, 중간에 Interceptor를 자유롭게 추가할 수 있습니다.

예를 들어서 Log 를 남기는 Interceptor를 먼저 적용하고, 그다음에 로그인 여부를 체크하는 인터셉터를 만들 수 있습니다.

 

지금까지 알아본 내용을 보면 Servlet Filter와 호출 되는 순서만 다르고, 제공하는 기능은 비슷해 보입니다.

 

그럼 왜 사용할까요?

그건 바로 Spring Interceptor가  Servlet Filter보다 편리하고, 더 정교하고 다양한 기능을 지원하기 때문입니다.

 


Spring Interceptor Interpace

 

Spring Interceptor를 사용하려면 HandlerInterceptor Interface를 구현하면 됩니다.

 

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response,
     Object handler) throws Exception {}
     
    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 {}
}

 

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

Spring Interceptor 호출 흐름

 

인터셉터 호출 흐름

 

[ 정상 흐름 ]

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

 

 

 

[  Spring Interceptor Exception Situation ]

 

 

[ 예외가 발생 시 ]

  • preHandle : 컨트롤러 호출 전에 호출된다.
  • postHandle : 컨트롤러에서 예외가 발생하면 postHandle은 호출되지 않는다.
  • afterCompletion : afterCompletion은 항상 호출된다. 이 경우 예외(ex)를 파라미터로 받아서 어떤 예외가 발생했는지 로그로 출력할 수 있다.

 

[ afterCompletion은 예외가 발생해도 호출된다.  ]

  • 예외가 발생하면 postHandle()는 호출되지 않으므로 예외와 무관하게 공통 처리를 하려면 afterCompletion()을 사용해야 한다.
  • 예외가 발생하면 afterCompletion()에 예외 정보(ex)를 포함해서 호출된다.

 


 

인터셉터는 SpringMVC 구조에 특화된 필터 기능을 제공한다고 정의하면 될 거 같습니다.

SpringMVC를 사용하고, 특별히 Filter를 꼭 사용해야 하는 상황이 아니라면 인터셉터를 사용하는 것이 더 편리할 거 같습니다.

 


마치며

 

오늘은 이전에서 다뤘던 인터셉터에 대한 개념을 좀 더 보충하는 포스팅을 작성했습니다.

다음은 인터셉터를 이용해서 로그 출력을 해보겠습니다.

 

위 포스팅은 김영한님의 Spring MVC 2편 - 백엔드 웹 개발 활용  강의를 참고했습니다

 

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 강의 - 인프런

웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있

www.inflearn.com

 

728x90