스프링 인터셉터도 서블릿 필터와 같이 공통 관심사항을 해결하는 기술이다.
기능도 훨씬 강력하다.
흐름은
HTTP 요청 -> WAS -> 필터 -> 디스패처서블릿 -> 스프링 인터셉터 -> 컨트롤러
이다.
스프링 인터셉터는 스프링MVC의 기능이기 때문에, 결국 디스패처 서블릿 이후에 등장하게 된다. 스프링MVC의 시작점이 디스패처 서블릿 이니까.
스프링 인터셉터의 제한은 저 흐름에서 컨트롤러로 가는 것을 막는 것이다.
얘도 똑같이 체인 기능이 있다.
다음이 실제 스프링 인터셉터의 인터페이스이다.
public interface HandlerInterceptor {
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은 컨트롤러 호출 전,
postHandle은 컨트롤러 호출 후,
afterCompletion은 완전하게 요청이 다 끝난 이후, 아마도 정말 클라이언트에게 응답 보내기 직전 같다. (즉, 응답 메시지에 모든 걸 넣은 후, render()를 거친 후 등)
저걸 설명하기 전에 잠깐 스프링 MVC에 Http 요청이 온 흐름을 다시 한번 생각해 보자
HTTP 요청 -> 디스패처 서블릿
디스패처 서블릿에서 요청과 컨트롤러(핸들러)에서 맵핑이 되는 게 있는 게 있는지 찾아봄(url 등으로, @PostMapping("/save")등의)
그 다음 그 핸들러를 처리할 수 있는 어댑터가 있는지 핸들러 어댑터 목록에서 조회
(왜냐하면 이건 기존의 코드를 수정하는 걸 막고, 확장에는 열려있기 때문에 우리가 원래 만들어 놨던 이 Spring MVC가 하는 요청의 처리에 맞춰줄 필요가 있음. 핸들러는 ModelView를 반환하게 할 의무가 있기 때문에, 우리가 원하는 정보(ModelView)와 요청에 대해 컨트롤러가 처리해 준 정보와 잘 엮어서 반환시키도록 해야하기 때문에 핸들러 어댑터는 그 역할을 하는 것이다.)
그 다음, 핸들러 어댑터를 통해서 핸들러(컨트롤러)를 실행하고 ModelView를 반환 받는다.
그 ModelView는 ViewResolver로 넘겨서 ModelView의 논리 이름이라던지 이런 것을 실제로 읽을 수 있는 물리 이름(주로 템플릿 경로와 확장자명을 포함한 실제로 접근 가능한 파일 명)으로 바꿔준 후, 그걸 포함하고 있는 VIew를 반환한다.
REST API는 좀 다를 듯 하다. ModelAndView 대신 HttpEntityMessageConverter를 통해 처리하고, return타입도 다를 것이고, 그것은 View를 거칠 필요가 없기 때문에 ViewResolver에서도 뭔가 어댑터 패턴으로 REST API에 대한 return은 뭔가 그냥 넘어가는 걸로 처리하고 끝낼 것 같다. REST API에 대한 View도 어댑터 패턴으로 존재하겠지.
그 다음 view.render() 하면 그 템플릿으로 가서 처리를 한다.
https://qwefdg3.tistory.com/272
위가 기본적은 스프링 MVC의 요청의 처리 흐름이었고, 다시 돌아와서
preHandle은 핸들러가 실행 되기 에 호출된다. (핸들러 어댑터 실행 전) 얘는 boolean을 반환하는데, false이면 아예 끝나버려서 뒤를 실행하지 않는다. 필터역할을 하는 것이다.
postHandle은 핸들러 실행 후 호출된다. ModelView 등 반환 이후.
afterCompletion은 view.render()로 응답 Http메시지에 응답내용이 모두 담겼을 때 호출한다.
응답 메시지 다 만들고, 보내기 직전.
만약 컨트롤러에서 예외 발생 시,
postHandler는 호출되지 않지만
afterCompletion은 호출된다.
이유는 저 위에 인터셉터 인터페이스 보면 afterCompletion은 예외도 받을 수 있게끔 해놨다.
그래서 예외와 무관하게 공통처리 하려면 afterCompletion()을 사용하면 된다.
인터셉터는 스프링 MVC에 특화된 필터기능을 제공하므로,
스프링 MVC를 사용하는 환경에서 특별히 꼭 필터를 사용해야 하는 상황이 아니라면 인터셉터를 사용하는 것이 좋다.
'스프링 > 4. 스프링 MVC-2' 카테고리의 다른 글
59. 스프링 인터셉터 로그인 필터 구현 (0) | 2023.09.09 |
---|---|
58. 스프링 인터셉터 요청로그 (0) | 2023.09.09 |
56. 인증 체크 필터 구현 (0) | 2023.09.09 |
55. 필터 구현 (0) | 2023.09.09 |
54. 필터, 인터셉터 (0) | 2023.09.08 |