인터셉터(Interceptor)란?
intercept의 의미가 '가로채다'이니 interceptor는 '가로채는 행위를 하는 주체' 정도로 정의할 수 있다.
그럼 interceptor는 무엇을 가로채는 것일까?
바로 클라이언트의 요청과 서버의 응답을 가로챈다. 그림에서 알 수 있듯이 클라이언트의 요청이 컨트롤러에 닿기까지 거치는 과정들이 있다. 이전 포스팅에서 클라이언트의 요청을 가장 먼저 만나는 Filter에 대해 알아보았는데 요청을 했을 때 정말 저런 순서를 거치는지 눈으로 확인해보자!
interceptor는 어떤 경우에 사용할까?
interceptor는 Controller 작업을 수행하기 전/후에 추가적인 작업을 진행하기 위해 사용한다.
예를 들어, 관리자 계정에서만 볼 수 있는 전체 회원의 정보를 일반 유저가 접근하여 볼 수 있게 된다면 아주 큰 문제이다.
그래서 요청이 들어오면 권한을 넘어선 요청인지 아닌지 판별해야 하는데 이런 작업을 위해 사용하는 것이 interceptor이다.
interceptor 구현하기
interceptor를 구현하기 위한 방법은 두 가지가 있다.
- HandlerInterceptor 인터페이스를 상속받아서 구현.
public class InterceptorEx1 implements HandlerInterceptor
- HandlerInterceptorAdapter 추상 클래스를 상속받아서 구현.
public class interceptorEx2 extends HandlerInterceptorAdapter
interceptor를 구현하기 위해 총 3가지의 메서드가 있다.
○ preHandle()
- 컨트롤러가 호출되기 전에 실행됨.
- 컨트롤러가 실행되기 이전에 처리해야 할 작업이 있을 경우 사용.
- 반환 타입이 boolean으로 true를 반환할 경우 preHandle() 실행 후 컨트롤러에 접근. 만약, false가 반환될 경우 뒤에 interceptor와 컨트롤러는 실행되지 않음.
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
○ postHandle()
- View로 넘어가기 이전에 호출됨.
- ModelAndView를 통해 View에 전달하기 위한 Model 객체를 참조하거나 조작할 수 있음.
- preHandle()에서 반환 값이 false일 경우 postHandle()은 실행되지 않음.
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
○ afterCompletion()
- View가 정상적으로 Rendering이 된 후에 실행.
- preHandle()에서 반환 값이 false일 경우 postHandle()은 실행되지 않음.
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
구현 예제
InterceptorEx1.java
public class InterceptorEx1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("================ InterceptorEx1의 preHandle() 실행 ================");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("================ InterceptorEx1의 postHandle() 실행 ================");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("================ InterceptorEx1의 afterCompletion() 실행 ================");
}
}
WebMvcConfig.java
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new InterceptorEx1());
}
}
InterceptorController.java
@Controller
public class InterceptorController {
@ResponseBody
@GetMapping("/home")
public String home(){
System.out.println("InterceptorController 실행 !");
return "Hello World !";
}
}
추가적으로 Filter까지 적용해보았는데 출력 결과를 보면 알 수 있듯이 Filter → Interceptor → Controller 순으로 실행되는 것을 확인할 수 있다.
다중 Interceptor
InterceptorEx2.java
public class InterceptorEx2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("================ InterceptorEx2의 preHandle() 실행 ================");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("================ InterceptorEx2의 postHandle() 실행 ================");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("================ InterceptorEx2의 afterCompletion() 실행 ================");
}
}
InterceptorEx1와 같은 메소드를 InterceptorEx2에 작성해주고 WebMvcConfig에서 InterceptorEx2를 추가해주자.
그러면 InterceptorEx2가 추가적으로 출력됐을 뿐 결과는 변함없는 것을 알 수 있다.
Interceptor의 구현하는 방법에 대해 알아보았고 Filter → Interceptor → Controller순으로 실행되는 것과 Interceptor를 여러 개 만들어서 적용 해보았다.
다음 포스팅에서는 AOP에 대해 다룰 예정이다.
▽ 도움을 주신 분들
'Spring > Spring' 카테고리의 다른 글
[Spring] Spring Triangle? 그게 뭔데 - IoC/DI (0) | 2022.06.30 |
---|---|
[Spring] Spring Triangle? 그게 뭔데 - AOP (0) | 2022.06.29 |
[Spring] Filter에 대해 알아보자 ! (0) | 2022.06.24 |
[spring] Spring MVC 구조 (0) | 2022.06.02 |
[spring] 컴포넌트 스캔 (0) | 2022.04.25 |