스프링 MVC Filter Interceptor
김영한님의 스프링 MVC 강의를 듣고 정리하였습니다. 😀
서블릿 필터
- 웹과 관련된 공통 관심사는 서블릿필터 또는 스프링 인터셉터를 사용하는것이 좋다.
필터 흐름
- HTTP 요청 > WAS > 필터 > 서블릿 > 컨트롤러
스프링 인터셉터
서블릿 필터와 같이 웹과 관련된 공통 관심 사항을 효과적으로 해결할 수 있는 기술
스프링 인터셉터 흐름
- HTTP 요청 > WAS > 필터 > 서블릿 > 스프링 인터셉터 > 컨트롤러
- 인터셉터는 컨트롤러 호출 전( preHandle ), 호출 후( postHandle ), 요청 완료 이후( afterCompletion )와 같이 단계적으로 잘 세분화 되어 있다.
- 예외가 발생하면 postHandler 호출 되지 않는다. 반면에, afterCompletion은 항상 호출된다.
코드
- 인터셉터 생성 후에는 WebConfig에서 addInterceptors를 추가해준다.
- registry.addInterceptor(new LogInterceptor()) : 인터셉터를 등록한다.
- order(1) : 인터셉터의 호출 순서를 지정한다. 낮을 수록 먼저 호출된다.
- addPathPatterns(“/**”) : 인터셉터를 적용할 URL 패턴을 지정한다.
-
excludePathPatterns(“/css/*”, “/.ico”, “/error”) : 인터셉터에서 제외할 패턴을 지정한다.
- 서블릿 필터의 경우 지역변수로 해결이 가능하지만, 스프링 인터셉터는 호출 시점이 완전히 분리되어 있다. 따라서 preHandle 에서 지정한 값을 postHandle , afterCompletion 에서 함께 사용하려면 어딘가에 담아두어야 한다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "*.ico", "/error");
}
}
? 한 문자 일치
* 경로(/) 안에서 0개 이상의 문자 일치
** 경로 끝까지 0개 이상의 경로(/) 일치
인증 체크 구현
-
소소 Tip Default 반환 타입은 내가 하고 싶은것만 오버라이드 하면 된다. (Java8 에서 부터 나온 기능)
-
LoginCheckInterceptor 클래스
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception {
String requestURI = request.getRequestURI(); log.info("인증 체크 인터셉터 실행 {}", requestURI);
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
log.info("미인증 사용자 요청");
//로그인으로 redirect response.sendRedirect("/login?redirectURL=" + requestURI); return false;
}
return true;
}
}
- WebConfig 클래스
- exclude 된 path에 대해서는 로직이 실행되지 않음
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "/*.ico", "/error");
registry.addInterceptor(new LoginCheckInterceptor())
.order(2)
.addPathPatterns("/**")
.excludePathPatterns(
"/", "/members/add", "/login", "/logout",
"/css/**", "/*.ico", "/error"
);
}
//...
}