[Spring] Interceptor

Manx·2022년 6월 14일
0

spring

목록 보기
16/24

인프런 '스프링 MVC 2편' - 김영한님의 강의 내용 정리


Spring Interceptor

Servelet Filter와 같이 공통 관심 사항을 효과적으로 해결할 수 있는 기술이다.

EX)

  • 모든 요청 URL을 Log로 남겨야한다.
  • 요청이 들어오기 전 수행할 수 있는 행동들을 일일히 컨트롤러에서 메서드를 호출하는 것이 아니라 모듈로 분리해 편리하게 사용할 수 있다.

호출 흐름

스프링 인터셉터는 서블릿과 컨트롤러 사이에서 컨트롤러 호출 직전에 호출된다.

HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러

  • HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러
  • HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터(적절하지 않은 요청, 컨트롤러 호출X)

사용방법

HandlerInterceptor interface를 구현하면 된다.

public interface HandlerInterceptor {
	default boolean preHandle(HttpServletRequest request, HttpServletResponse response,
    							Object handler) throws Exception {}
    
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 : 요청 완료 이후

서블릿 이후에 호출되기 때문에 model 정보도 불러올 수 있다.


호출 흐름

정상 흐름

  • preHandle : 컨트롤러 호출 전 호출
  • preHandle = true : 다음으로 진행
  • preHandle = false : 종료, 다른 인터셉터는 물론 핸들러 어댑터도 호출하지 않는다.
  • postHandle : 컨트롤러 호출 후 호출
  • afterCompletion : 뷰가 랜더링 된 이후에 호출

예외 상황

  • 컨트롤러에서 예외가 발생하면 postHandle은 호출되지 않는다.
  • afterCompletion은 항상 출력되고, 파라미터로 예외(ex)가 있기 때문에 예외를 파악할 수 있다.

스프링 인터셉터로 로그인 사용자 체크하기

@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;
	}
}

인터셉터 등록

excludePathPatterns를 통해 편리하게 등록할 수 있다.
인터셉터가 생성될 때 검사하므로 LoginCheckInterceptor 내부에서 검사할 필요가 없다.

@Configuration
public class WebConfig implements WebMvcConfigurer {
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
    
	registry.addInterceptor(new LoginCheckInterceptor())
			.order(1)
			.addPathPatterns("/**")
			.excludePathPatterns("/", "/members/add", "/login", "/logout",
								"/css/**", "/*.ico", "/error");
	}
}

서블릿 필터에 대한 내용도 학습했지만, 간단하게 정리하기 위해 생략했다.
인터셉터가 더 많고 편리한 기능을 제공해주기 때문에 굳이 필터를 사용해야하는 상황이 아니라면 인터셉터를 사용한다.

0개의 댓글