Interceptor란?
org.springframework.web.servlet의 HandlerInterceptor 인터페이스로, 스프링 MVC에서 웹 애플리케이션 내에 특정한 uri 호출을 가로채는 역할을 함
특징
- Dispatcher Servlet이 Controller를 호출하기 전 / 후에 인터셉터가 끼어들어 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공
- Request, Response 조작 불가능
- 스프링 컨텍스트에서 동작
처리 과정
디스패처 서블릿이 핸들러 매핑을 통해 컨트롤러를 찾도록 요청하는데, 그 결과로 실행 체인(HandlerExecutionChain)을 돌려줌
여기서 1개 이상의 인터셉터가 등록되어 있다면 순차적으로 인터셉터들을 거쳐 컨트롤러가 실행되도록 하고,
인터셉터가 없다면 바로 컨트롤러를 실행
디스패처 서블릿이 여러 인터셉터 목록을 가지고 있고, for문으로 순차적으로 실행시킨다.
그리고 true를 반환하면 다음 인터셉터가 실행되거나 컨트롤러로 요청이 전달되며, false가 반환되면 요청이 중단된다.
=> 그래서 다른 Request/Response 객체를 넘겨줄 수 없음
언제 사용되나요?
- 세부적인 보안 및 인증 / 인가 공통 작업
- API 호출에 대한 로깅 또는 검사
- Controller로 넘겨주는 정보 가공
- JWT 토큰 정보를 파싱해서 컨트롤러에게 사용자의 정보를 제공하도록 가공 가능
- 여러 목적으로 API 호출에 대한 정보들을 기록해야 하는 상황에 HttpServletRequest나 HttpServletResponse를 제공해주는 인터셉터는 클라이언트의 IP나 요청 정보들을 기록하기에 용이
예시 (세션을 통한 인증)
요청을 받아 들이기 전, 세션에서 로그인한 사용자가 있는지 확인해보고 없다면 로그인 페이지로 redirect 시킬 수 있습니다.
Interceptor가 없다면 모든 컨트롤러마다 해당 로직을 넣어야 하니, 꽤나 번거롭고 비효율적입니다.
혹은, 주기적으로 결과 페이지에 등장하는 데이터들을 인터셉터에서 응답을 가로채어 데이터를 추가한 다음 보낼 수도 있죠.
메일 알림 개수를 조회한 후 추가한다거나, 헤더 데이터 같은 것들이 있을 수 있습니다.
HandlerInterceptor 인터페이스 메소드
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() : Controller가 호출되기 전에 실행, 컨트롤러 이전에 처리해야 하는 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우에 사용
- postHandle() : Controller가 호출된 후에 실행 (View 렌더링 전), 컨트롤러 이후에 처리해야 하는 후처리 작업이 있을 때 사용 가능
컨트롤러가 반환하는 ModelAndView 타입의 정보가 제공되는데,
최근에는 JSON 형태로 데이터를 제공하는 RestAPI 기반의 컨트롤러(@RestController)를 만들면서 자주 사용되지 않음
- afterCompletion() : 모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행 (View 렌더링 후), 요청 처리 중에 사용한 리소스를 반환할 때 사용 가능
'CS' 카테고리의 다른 글
[CS] Spring 빈 스코프(Bean Scope) (0) | 2024.05.01 |
---|---|
[CS] Spring PSA (1) | 2024.05.01 |
[CS] Spring Filter (0) | 2024.04.30 |
[CS] Spring DI란? (0) | 2024.04.30 |
[CS] Spring에서 Bean 등록하는 방법 (0) | 2024.04.29 |