인터셉터

정병웅·2024년 7월 4일
0

Spring 강의

목록 보기
5/6

필터를 구현 하고 나서 스프링 MVC에서 사용되는 인터셉터에 대해서 배웠고, 인터셉트를 구현하는 걸 정리해 봤당,,,!!

사용 이유

  1. 웹과 관련된 공통 사항을 효과적으로 처리 가능
  2. 필터보다 좀 더 세세하게 컨트롤이 가능
  3. 스프링 MVC에서 제공 되어 스프링 부트에 최적화가 잘 되어있음.

동작 흐름

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

동작 흐름 제어 예시

  1. 로그인 사용자
    HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러
  2. 비 로그인 사용자
    HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 (적절한 요청이 아니기 때문에 컨트롤러 호출 X)

성공시

예외 발생 시

구현 방법

1. HandlerInterceptor 인터페이스 구현

요청 로그를 남기는 인터셉터

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 uri = request.getRequestURI();
        String uuid = UUID.randomUUID().toString();
		// 추후 afterCompletion에서 사용 할 수 있게
        // uuid를 request에 set함.
        request.setAttribute(LOG_ID, uuid);
        // HandlerMethod를 이용해서 어떤 컨트롤러가 호출 되는지 확인 가능
        if (handler instanceof HandlerMethod) {
        	// HanderlerMethod에는 호출할 컨트롤러 메서드의 모든 정보가 들어있음.
            HandlerMethod hm = (HandlerMethod) handler;
        }
        log.info("REQUEST [{}][{}][{}]", uuid, uri, handler);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

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

        log.info("RESPONSE [{}][{}][{}]", logId, uri, handler);
        if (ex != null) {
            log.info("Exception :: {}",ex);
        }
    }
}
  1. preHandle
  • 컨트롤러 호출 전에 호출 되는 메서드
  • 파라미터로 받는 handler로 ModelAndView 정보도 확인 가능하다.
  • return 값이 true 이면 다음 진행, false이면 컨트롤러 호출 하기 전에 진행 종료
  1. postHandle
  • 컨트롤러 호출 후 호출 되는 메서드
  • 예외가 발생 할 경우 호출 X
  1. afterCompletion
  • 요청 완료 이후(뷰가 렌더링 된 이후) 호출 되는 메서드
  • preHadle에서 request 객체를 유지해서 afterCompletion에서 사용이 가능하다.
  • 예외가 발생 해도 호출 보장.

비인증 로그인 유저를 처리하는 인터셉터

@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();
        if (session == null || request.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
            log.info("미인증 사용자 요청");
            response.sendRedirect("/login?redirectURL=" + requestURI);
            return false;
        }
        return true;
    }
}

WebConfig로 인터셉터 등록


@Configuration
public class WebConfig implements WebMvcConfigurer {
   
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor())
                .order(1)
                .addPathPatterns("/**")
                .excludePathPatterns("/css/**", "/*.icon", "/error");
        registry.addInterceptor(new LoginCheckInterceptor())
                .order(2)
                .addPathPatterns("/**")
                .excludePathPatterns("/", "/login", "/logout", "/members/add", "/css/**", "/*.ico", "/error");
    }
  1. addIntercpetors() 로 인터셉터 등록
  2. order는 등록 할 인터셉터의 호출 순서를 지정
  3. addPathPatterns("") 를 사용해서 인터셉터를 적용할 URL 패턴 지정
  4. excludePathPatterns() 를 사용해서 인터셉터에서 제외할 패턴 지정

결론

필터보다 스프링 MVC에서 제공하는 인터셉터를 사용해서 보다 세세하게 설정하고 제어하자!

profile
인생은 IT 노가다

0개의 댓글