오늘은 handler interceptor 에 대한 이야기를 조금 해보고자 한다.
Filter 는 자바 servlet 에서 제공하는 기술이지만 interceptor는 spring에서 제공하는 기술로써
세션 인증과 관련된 부분을 공부하다가 적어본다.
▶ 그래서 interceptor 가 뭔가요?
spring MVC 에서 인터셉터란 결국
지정된 URI에 관한 호출을 가로채는 역할을 하는 기능입니다.
이러한 호출을 가로채서 뭐하냐 싶지만
우리는 로그인을 한다거나 어떠한 게시물에 조회수를 올린다거나 하는 작업을 할 때 와 같은
공통된 관심사를 컨트롤 하기 위해서 사용하는 것 이다.
이는 이전 게시글인 Filter 와 같은데 두개의 차이점은 확실히 존재한다.
▶ Filter 와 Interceptor의 차이점
Filter와 Interceptor는 그 기능이 매우 흡사하여 나와같은 초보들이 가장 많이 헷갈려하는게
두 기능은 확연한 차이가 존재한다.
위 사진을 보면 해당 차이를 조금 더 확실하게 알 수 있는데
Filter는 요청을 보내면 Tomcat과 같은 WAS 서버에 들어오자마자 작동되는 것으로
Spring의 영역에 접근하여 사용하기가 어렵습니다.
반면에 interceptor는 Spring 내에서 관리되는 기능이기에 Spring의 영역 내에서 사용되고 있는 것을 볼 수 있습니다.
이것으로 인해서 알 수 있는 차이는 생성된 Bean에 접근이 용이한가로 볼 수 있습니다.
◆ 차이점 정리
▶ Interceptor와 Filter는 호출 시점의 차이
- Filter는 Dispatcher Servlet 호출 전(WAS의 단계)
- Interceptor은 Dispatcher Servlet 호출 후 실행 됨
▶ Interceptor 의 용도
- 인증 인가 등과 같은 공통 작업
- Controller로 넘어가는 정보의 가공
- API 호출에 대한 로깅 또는 감사
▶ Filter의 용도
- 보안 관련 공통 작업
- 모든 요청에 대한 로깅
- 이미지, 데이터 압축 및 문자열 인코딩
이제 이어지는 사용법을 알아보자
Handler Interceptor는 Interface 이므로 class 에 implements 하여 사용하면 된다.
public interface HandlerInterceptor {
// controller 호출 전에 실행 (핸들러 어댑터 실행 전)
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
// controller 호출 후에 실행 (핸들러 어댑터 호출 후)
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
// view의 랜더링 이후 실행
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
위 코드가 HandlerInterceptor의 기본 모습이며 사용처는 내부에 적어두었다.
이를 사용하여 만든 간단한 예문을 적고 마무리 이 글을 마무리 하고자 한다.
▶ 예문
LOG 를 찍어 흐름 확인하기
@Slf4j
public class LogInterceptor implements HandlerInterceptor {
public static final String LOG_ID = "logId";
@Override // controller 호출 전에 실행 (핸들러 어댑터 실행 전)
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String reqURI = request.getRequestURI();
String uuid = UUID.randomUUID().toString();
request.setAttribute(LOG_ID, uuid);
//@RequestMapping : HandlerMethod
// 정적 리소스 : ResourceHttpRequestHandler
if (handler instanceof HandlerMethod) {
HandlerMethod hm = (HandlerMethod) handler;
// 호출할 컨트롤러의 메서드의 모든 정보
}
log.info("REQ [{}][{}][{}]",uuid, reqURI,handler);
return true;
}
@Override // controller 호출 후에 실행 (핸들러 어댑터 호출 후)
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
log.info("postHandle [{}]", modelAndView);
}
@Override // view의 랜더링 이후 실행
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
String reqURI = request.getRequestURI();
String logId = (String) request.getAttribute(LOG_ID);
log.info("RES [{}][{}]", logId, reqURI);
if (ex != null) {
log.error("afterCompletion error!", ex);
}
}
}
※ Interceptor를 정의한 클레스
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// logInterceptor register
registry.addInterceptor(new LogInterceptor()) // 인터셉터 등록
.order(1) // 인터셉터의호출 순서를 지정, 낮을수록 먼저 호출
.addPathPatterns("/**") // 인터셉터를 적용할 URL패턴 지정
.excludePathPatterns("/css/**", "/*.ico", "/error"); //인터셉터에서 제외할 패턴 지정
}
※ Interceptor 등록
♣ 참고 및 강의
https://inf.run/GMo43 - 김영한의 스프링MVC2
스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 강의 - 인프런
웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있
www.inflearn.com
'Web > spring' 카테고리의 다른 글
servlet filter (0) | 2024.01.19 |
---|