Interceptor 사용 예제

YH·2023년 3월 1일
0

Interceptor 사용 예제
1. 모든 요청에 대한 로그를 남기는 Interceptor

@Slf4j
public class LogInterceptor implements HandlerInterceptor {
    public static final String LOG_ID = "logId";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = 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("REQUEST [{}][{}][{}]", uuid, requestURI, handler);
        return true; //false 인 경우 다음으로 진행되지 않고 종료됨
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle [{}]", modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        String requestURI = request.getRequestURI();
        String uuid = request.getAttribute(LOG_ID).toString();

        log.info("RESPONSE [{}][{}]", uuid, requestURI);
        if (ex != null) {
            log.error("afterCompletion error!!", ex);

        }
    }
}
  • 인터셉터는 호출 시점이 분리되어 있기 때문에(각 메소드로 나뉘어져 있기 때문에) preHandler에서 지정한 값을 postHandler나 afterCompletion에서 사용하기 위해서는 아래와 같이 request에 담아서 사용 할 수 있음

    request.setAttribute(LOG_ID, uuid);

  • 핸들러 정보는 어떤 핸들러 매핑을 사용하는가에 따라 달라진다.
  • 스프링에서는 일반적으로 @Controller, @RequestMapping을 활용한 핸들러 매핑을 사용하는데, 이 경우 핸들러 정보로 HandlerMethod가 넘어온다.
  • /resources/static와 같은 정적 리소스가 호출 되는 경우에는 ResourceHttpRequestHandler가 핸들러 정보로 넘어옴
  • 예외가 발생하는 경우에는 postHandler가 호출되지 않음, afterCompletion은 예외가 발생해도 호출 됨

1-1. Interceptor 등록

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor())
                .order(1)
                .addPathPatterns("/**")
                .excludePathPatterns("/css/**", "/*.ico", "/error");
    }
}
  • WebMvcConfigurer에서 제공하는 addInterceptors()를 사용해서 인터셉터를 등록
  • excludePathPatterns()를 사용하여 인터셉터에서 제외할 패턴을 지정
  • PathPatterns에 대한 공식 문서는 링크 참조 : PathPatterns
  1. 인증 체크 Interceptor
@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;
	}
}

2-2. Interceptor 등록

@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");
	}
//...
}
  • Interceptor를 적용하지 않을 경로를 excludePathPatterns()에 지정하여 Filter에 비해 간단하게 설정할 수 있다.
profile
하루하루 꾸준히 포기하지 말고

0개의 댓글