10. Spring/BOOT

스프링 부트 MVC - Handler Interceptor

THE HEYDAZE 2022. 4. 14. 08:51
  OS   Windows 10 PRO 64bit 버전 20H2 (OS 빌드 19042.867)
  Framework   Spring Boot 2.6.6
  EditTool   Inellij IDEA 2020.1.3
  BuildTool   Maven

구조

 

HanlderInterceptor
  preHandle 컨트롤러 실행 전 수행한다. 반환 값이 true일 경우 컨트롤러로 진입하고 false일 경우 진입하지 않는다. Object handler는 진입하려는 컨트롤러의 클래스 객체가 담겨있다
  postHandle 컨트롤러 실행 후 View가 랜더링 되기 전에 수행한다.
  afterCompletion 컨트롤러 실행되고 view가 랜더링 된 후에 실행된다.
  afterConcurrentHandlingStarted 비동기 요청 시 PostHandle과 afterCompletion이 수행되지 않고 afterConcurrentHandlingStarted가 수행된다. (상위 버전에서 사라짐)

 

WebMvcConfigurer addInterceptor()
  addInterceptor 적용할 HandlerIntercpor 구현체 클래스
  addPathPatterns /*, /**/list, /sign-in 로 매칭하고 해당 url 일 때만 HandlerIntercpor 구현체 적용
  excludePathPatterns /*, /**/list, /sign-in 로 매칭하고 해당 url 일 때만 HandlerIntercpor 구현체 적용하지 않음
  pathMatcher AntPathMatcher(url) 로 매칭하고 해당 url 일 때만 HandlerInterceptor 구현체 적용
  order HanlderInterceptor 순서 적용

 

AntMatcher 참고 url

https://syaku.tistory.com/297

코드
@Configuration
@RequiredArgsConstructor
public class MvcConfig implements WebMvcConfigurer {

    private final CustomInterceptor customInterceptor;


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor)
                .addPathPatterns("/*")
                ;
    }
}
@Controller
public class TestController {
    
    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @PostMapping("/login-do")
    public String loginDo() {
        return "redirect:board";
    }
    

    @GetMapping("/board")
    public String board() {
        return "board";
    }

}
@Slf4j
@Component
public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("[Controller 진입전]");
        log.info("request url -> {}", request.getRequestURL());

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        SessionInfo sessionInfo = (SessionInfo) request.getSession().getAttribute("sessionInfo");
        log.info("[Controller 진입 후]");

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("[View 렌더링 된 후 실행]");
    }


}

 

위 처럼 코드를 짜는 경우 모든 url 에 대해서 CustomIntercepter 를 실행한다

이렇게 된 경우 CustomIntercepter 에서 특정 url 처리를 하지 않는 경우 url 을 돌면서 값이 바뀔 수 있다

 

공통적으로 처리할 것이 아니라면 config 에서 해당 url 에만 정해준다

 

@Configuration
@RequiredArgsConstructor
public class MvcConfig implements WebMvcConfigurer {

    private final CustomInterceptor customInterceptor;


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor)
                .addPathPatterns("/login-do")
                ;
    }
}

 

간단한 구조

간단 구조

HandlerMapping 에서 request 로 넘어온 /login url 이 있는 지 매핑해줌

HandlerAdapter 에서 mapping 된 url 에 맞는 contoller 를 실행

HandlerIntercepter 에서 controller 가 실행 되기 전에 가로채서 실행

 

Filter, Interceptor, AOP 차이는 아래 참고 바람
참고

전체적인 흐름
https://livenow14.tistory.com/61
https://livenow14.tistory.com/61


https://velog.io/@hsw0194/Spring-MVC-HandlerMapping%EC%9D%98-%EB%8F%99%EC%9E%91%EB%B0%A9%EC%8B%9D-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-1%ED%8E%B8


https://goddaehee.tistory.com/154