Interceptor 란
사전적 의미로 "낚아채다" 라는 뜻처럼 사용자 요청이 Filter, DispatchServlet에 의해
요청에 알맞는 컨트롤러를 찾아 컨트롤러에게 전달되기 전 요청(HttpRequest, HttpResponse)을
낚아채어 개발자가 원하는 추가적인 작업을 진행하기 위해 사용한다.
위 이미지를 보면 사용자의 모든 요청을 Front Controller 라고 하는 DispatcherServlet이 받는다.
요청받은 DispatcherServlet은 HandlerMapping 을 통해 요청에 맞는 적절한 Controller를 찾아
요청을 넘기게 되는데 Controller로 요청을 넘기기전에 Interceptor가 요청을 가로챈다.
요청을 가로채어 필요한 작업을 진행한 후 다시 Controller 에게 넘기고 요청 받은 Controller는
요청 처리를 완료한 후 DispatcherServlet에게 요청을 넘겨 사용자에게 View를 보여주게 된다.
View 로 보여주기 전에 Interceptor는 또 요청을 가로채어 필요한 작업을 진행한 후
DispatcherServlet에게 요청을 넘겨 View를 보여주게 된다.
Filter 와 Interceptor 의 차이점
Filter 는 DispatcherServlet에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해
부가작업을 처리할 수 있는 기능을 제공한다.
Inteceptor는 Spring 이 제공하는 기술로써, DispatcherServlet이 컨트롤러를 호출하기 전/ 처리가 완료된 후에
필요한 작업을 진행할 수 있다.
DispatcherServlet은 Spring의 가장 앞단에서 존재하는 Front Controller 이므로 Filter 는
Spring 범위 밖인 톰캣과 같은 웹 컨테이너에 의해 관리된다.
위 내용은 위 이미지와 같다.
HandlerInterceptor 메서드
preHandler(HttpServletRequest request, HttpServletResponse response, Object handler)
컨트롤러가 호출되기 전 실행되는 메서드이다.
컨트롤러가 호출되기 전 처리 해야할 작업이 있는경우 혹은 요청정보를 가공하거나 추가하는 경우
사용한다.
위 이미지를 보면 DispatcherServlet 에서 HandlerMapping 을 통해 적절한 Controller를 찾고
요청을 Controller로 보내기 전에 Interceptor의 preHandle이 가로채어 필요한 작업을 진행한 후
넘긴다.
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView)
컨트롤러에 의해 요청 처리가 완료되고 화면(View)이 생성되기 전에 실행되는 메서드이다.
postHandle 메서드는 preHandle과 다르게 ModelAndView 객체값을 인자값으로 받는다.
ModelAndView 객체를 통해 컨트롤러에서 View 로 넘길 데이터를 조작할 수 있는데
주로 공통적으로 View에 전달할 값이 있을 경우 사용한다.
위 이미지를 보면 Controller에 의해 요청처리가 완료되어 View로 가기전에 Interceptor의
postHandle이 가로채어 필요한 작업을 완료한 후 요청을 넘긴다.
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex)
모든 View에서 최종 결과를 생성하는 일 등 모든 작업이 완료된 후에 실행된다.
요청 처리중에 사용한 리소스를 반환해주기 적당한 메서드이며, preHandle() 메서드에서 리턴값이
false인 경우 실행되지 않는다.
비동기적 요청 처리시에는 호출되지 않는다.
HandlerInterceptor 사용하기
1. HandlerInterceptor implements 하기
HandlerInterceptor를 적용할 class 파일을 생성한다.(본인은 CommonInterceptor 라는 파일 생성)
CommonInterceptor 에 HandlerInterceptor 를 구현하여 설정한다.
CommonInterceptor
@Component
public class CommonInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("--------------PRE HANDEL 동작---------------");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
System.out.println("--------------POST HANDEL 동작---------------");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
System.out.println("--------------VIEW 완료 AFTER HANDEL 동작---------------");
}
}
@Component
개발자가 직접 작성한 Class 를 Bean 으로 등록하기 위한 어노테이션이다.
해당 어노테이션은 @Controller, @Service, @Repository 에도 적용되어 있는걸 확인할 수 있다.
위 어노테이션은 @Component 어노테이션의 구체화된 어노테이션이라고 볼 수 있다.
Spring Boot 실행 시 @ComponentScan 어노테이션에 의해 @Component, @Controller, @Service, @Repository,
@Configration 어노테이션을 찾아 Spring Bean 으로 등록해준다.
2. Interceptor 설정하기(추가하기)
구현한 HandlerInterceptor 인 CommonInterceptor 가 동작할 수 있도록 WebMvcConfigurer 를 구현한다.
WebMvcConfig 라는 클래스를 생성하여 WebMvcConfigurer 를 구현한다.
addInterCeptors Default Method 를 구현하여 인터셉터를 추가한다.
WebMvcConfig.class
@Configuration
Bean 등록 클래스로 사용하기 위한 어노테이션 사용
addInterceptors(InterceptorRegistry registry)
인터셉터를 적용하기 위해 WebMvcConfigurer 인터페이스의 Default Method 를 오버라이딩
InterceptorRegistry registry.addInterceptor(new CommonInterceptor())
InterceptorRegistry 클래스의 addInterceptor() 메서드를 통해 커스텀 인터셉터를 추가한다.
InterceptorRegistry 클래스의 addInterceptor 메서드는 HandlerInterceptor 를 매개변수로 받는다.
CommonInterceptor 는 @Component 어노테이션을 통해 Bean 으로 등록 했기 때문에
new 키워드로 호출하여 사용했다.
addPathPatterns("/**")
인터셉터에 포함 되어야 할 URL 패턴을 추가한다.