DAY64(1) - 스프링 인터셉터

은나현·2023년 4월 26일
0

📌 1. 스프링 인터셉터

📍 1-1. 인터셉터란

  • 스프링 인터셉터도 서블릿 필터와 같이 웹과 관련된 공통 관심 사항을 효과적으로 해결할 수 있는 기술이다.
    • 서블릿 필터가 서블릿이 제공하는 기술이라면, 스프링 인터셉터는 스프링 MVC가 제공하는 기술이다.
    • 둘 다 웹과 관련된 공통 관심 사항을 처리하지만, 적용되는 순서와 범위 그리고 사용방법이 다르다.
    • 필터보다 인터셉터가 더 디테일한 컨트롤이 가능하다.

📍 1-2. 스프링 인터셉터 흐름

  • HTTP요청 - WAS -> 필터 -> 서블릿 ->
    스프링 인터셉터(인터셉터1 -> 인터셉터 2 -> ...) -> 컨트롤러
    • 스프링 인터셉터는 디스패처 서블릿과 컨트롤러 사이에서 컨트롤러 호출 직전에 호출된다.
    • 스프링 인터셉터는 스프링 MVC가 제공하는 기능이기 때문에 결국 디스패처 서블릿 이후에 등장하게 된다.
      • (스프링 MVC의 시작점은 디스패처 서블릿)
  • 스프링 인터셉터 체인 :
    • 스프링 인터셉터는 체인으로 구성되는데 중간에 인터셉터를 자유롭게 추가할 수 있다. 예를 들어서 로그를 남기는 인터셉터를 먼저 적용하고, 그 다음에 로그인 여부를 체크하는 인터셉터를 만들 수 있다.
  • 스프링 인터셉터는 서블릿 필터보다 편리하고, 더 정교하고 다양한 기능을 지원한다.

➕ Interceptor 경로

  • 스프링 인터셉터에도 URL패턴을 적용할 수 있는데, 서블릿 URL패턴과는 다르고 매우 정밀하게 설정할 수 있다.
    • /** : 모든 경로에 대해서 적용할 때
      • 예 : /resources/** , /css/**
    • /* : 1개의 어떠한 경로에 상관없이 사용
      • 예 : /resources/*.png , /*.ico

📍1-3. 스프링 인터셉터 인터페이스

  • 스프링 인터셉터를 사용하려면 HandlerInterceptor 인터페이스를 구현한다.
    • 서블릿 필터의 경우 단순하게 doFilter()하나만 제공되는 반면 인터셉터는 컨트롤러 호출 전(preHandle), 호출 후(postHandle), 요청 완료 이후(afterCompletion)와 같이 단계적으로 세분화되어 있다.
  • preHandle : 컨트롤러 호출 전에 호출된다.
    • preHandle의 응답값이 true이면 다음으로 진행하고, false이면 더는 진행하지 않는다.
    • false인 경우 나머지 인터셉터는 물론이고 핸들러 어댑터도 호출하지 않는다.
  • postHandle : 컨트롤러 호출 후에 호출된다.
  • afterCompletion : 뷰가 렌더링된 이후에 호출된다.
  • 인터셉터 코드 예시
    • // HandlerInterceptor 구현
      public class LogInterceptor implements HandlerInterceptor{
      	// 전역 스태틱 상수
      	public static final String LOG_ID = "logId";
      	// preHandle 에서 컨트롤러 호출 직전에 랜덤 uuid, requestURI 출력
      	@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);
      		System.out.println("[interceptor] uuid : " + uuid);
      		System.out.println("[interceptor] requestURI : " + requestURI);
      		return true; // false로 전환 시 진행하지 않음
      	}
      	// 컨트롤러 호출 후 뷰, 모델 출력
      	@Override
      	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
      			ModelAndView modelAndView) throws Exception {
      		System.out.println("[interceptor] postHandle : " + modelAndView);
      	}
      	// 뷰 렌더링까지 끝난 후 요청에 담았던 logId, requestURI 출력
      	@Override
      	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
      			throws Exception {
      		String requestURI = request.getRequestURI();
      		String logId = (String)request.getAttribute(LOG_ID);
      		System.out.println("[interceptor] logId : " + logId);
      		System.out.println("[interceptor] requestURI : " + requestURI);
      	}
      }

📍1-4. 스프링 인터셉터 등록

  • 스프링 인터셉터를 등록하려면 WebMvcConfigurer 인터페이스를 구현하고 @Configuration 어노테이션을 사용한다.
    • addInterceptors 내에서 registry.addInterceptor() 메서드로 등록한다.
  • 인터셉터 등록 코드 예시
    @Configuration
    public class WebConfig implements WebMvcConfigurer{
    	// addInterceptors 구현
    	@Override
    	public void addInterceptors(InterceptorRegistry registry) {
    		// 인터셉터 객체 생성해 registry에 등록하고 설정
    		registry.addInterceptor(new LogInterceptor())
    				.order(1)
    				.addPathPatterns("/**")		// 모든 경로 전체 가능
    				.excludePathPatterns("/css/**","/*.ico", "/error");
    	}
    }
  • addInterceptor() : 인터셉터 등록
  • order() : 인터셉터 순서 설정
  • addPathPatterns() : 인터셉터 실행할 경로 설정
  • excludePathPatterns() : 인터셉터 실행 제외할 경로 설정

0개의 댓글