SpringBoot에서 쉽고 빠르게 Interceptor를 적용하는 방법을 알아보겠습니다.
스프링 인터셉터도 서블릿 필터와 같이 웹과 관련된 공통 관심 사항을 효과적으로 해결할 수 있는 기술입니다.
서블릿 필터가 서블릿이 제공하는 기술이라면, 스프링 인터셉터는 스프링 MVC가 제공하는 기술입니다.
둘다 웹과 관련된 공통 관심 사항을 처리하지만, 적용되는 순서와 범위, 그리고 사용방법이 다릅니다.
Spring에서 서블릿 필터를 적용하고 싶다면 아래 링크 클릭!
인터셉터 흐름
HTTP 요청 -> WAS -> 필터 -> 서블릿(dispatcherservlet) -> 스프링 인터셉터 -> 컨트롤러
인터셉터 특징
1. 스프링 인터셉터에 URL 패턴을 적용할 수 있는데, 서블릿 URL 패턴과는 다르고, 매우 정밀하게 설정할 수 있습니다.
2. 서블릿 필터의 경우 단순하게 doFilter() 하나만 제공되지만 인터셉터는 컨트롤러 호출 전(preHandle), 호출 후(postHandle), 요청 완료 이후(afterCompletion)와 같이 단계적으로 잘 세분화 되어 있다.
** (예외 발생 시 postHandle은 실행이 안되고, preHandle, afterCompletion만 실행된다.)
3. 서블릿 필터의 경우 단순히 request , response 만 제공했지만, 인터셉터는 어떤 컨트롤러( handler )가 호출되는지 호출 정보도 받을 수 있다. 그리고 어떤 modelAndView 가 반환되는지 응답 정보도 받을 수 있다.
소스 코드
TestInterceptor.java
- HadlerInterceptor를 구현하면 Spring Interceptor를 사용할 수 있다.
package com.bumblebee.dailyspecial.domain.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("preHandle");
String requestURI = request.getRequestURI();
log.info(requestURI);
return true; // return true면 정상 호출, 다음 인터셉터나 컨트롤러 호출한다.
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("afterCompletion");
}
}
위에서 작성한 인터셉터를 등록해줘야 합니다.
WebConfig.java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor())
.order(1) // Interceptor 적용 순서
// filter와 다르게 매우 정밀하게 url 패턴 적용이 가능하다.
.addPathPatterns("/**") // 적용될 url 패턴
.excludePathPatterns("/css/**", "/*.ico", "/error"); //제외될 url 패턴
}
}
TestInterceptor 출력 화면
** Interceptor 주의 사항
서블릿 필터의 경우 (init, doFilter, destroy) 메소드에서 공유할 변수를 지역변수로 해결이 가능하지만,
스프링 인터셉터는 호출 시점이 완전히 분리되어 있습니다.
따라서 preHandle 에서 지정한 값을 postHandle , afterCompletion 에서 함께 사용하려면 어딘가에 담아두어야 합니다. TestInterceptor 도 싱글톤 처럼 사용되기 때문에 맴버변수를 사용하면 위험합니다.
따라서 request 에 담아두었다가( request.setAttribute(test, 123) ).
이 값은 afterCompletion 에서 request.getAttribute(test) 로 찾아서 사용하면 됩니다.
'Spring' 카테고리의 다른 글
[Spring] 동시성 해결(ThreadLocal) (0) | 2022.09.06 |
---|---|
토이 프로젝트 _ STEP 03(Web Application 개발) (0) | 2022.08.15 |
[SpringBoot] Filter 적용하기 (0) | 2022.06.22 |
토이 프로젝트 _ STEP 02(AWS S3) (0) | 2022.06.12 |
토이 프로젝트 _ STEP 02(AWS RDS) (0) | 2022.06.11 |