스프링/4. 스프링 MVC-2

57. 스프링 인터셉터

sdafdq 2023. 9. 9. 14:00

스프링 인터셉터도 서블릿 필터와 같이 공통 관심사항을 해결하는 기술이다.

 

 

기능도 훨씬 강력하다.

 

흐름은

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