du.study기록공간

[Spring MVC] Handler Interceptor 본문

스프링

[Spring MVC] Handler Interceptor

du.study 2019. 11. 10. 16:33
728x90

이번에는 핸들러 인터셉터에 대해서 기록하려 합니다.

Spring에서는 Interceptor라는 기능을 제공하는데, 이 Interceptor를 통해서 dispatcher로 들어온 요청들을 가로챈다음 특정 작업을 진행할 수 있게 도아줍니다. 이를 통해서 요청의 전,후 처리가 가능하며, 필자는 현재 로그인, 각 api별 권한확인 등을 위해서 Interceptor를 사용하고 있습니다.

 

Interceptor 를 사용하려면 Class에 implements HandlerInterceptor 를 지정해준 후, 관련 메서드에 기능을 구현해야 합니다. 

public class FirstIntercepter implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

(Intercepter에 implements HandlerIntegerceptor 를 설정한 직후의 모습)

 

preHandle : 핸들러가 실행되기 전에 실행되며,핸들러 정보를 같이 받아올 수 있기에 만약 필요하다면 각 핸들러에 맞는 사전 작업을 진행할 수 있습니다. 그리고 return 값을 true로 지정해야 다음 요청으로 진행이 됩니다.

 

postHandle : 핸들러가 실행이 되었고, 뷰 렌더링 이전에 실행됩니다. ModelAndView를 받아오고 있어, 만약 뷰에 추가로 전달이 필요한 값을 전달할 수 있으며, 후처리가 필요한 작업에 사용됩니다.  특이한점은 비동기 요청에서는 호출되지 않습니다. 자세한 내용을 아래 docs에 나와있는데, 비동기의 경우에는 다른 메서드가 호출되게 됩니다.

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/AsyncHandlerInterceptor.html

 

afterCompletion : View까지 전부 그리고 난 후, 호출되는 메서드 입니다. 이 요청 역시 비동기 요청에는 호출되지 않는 메서드 입니다.

 

 

해당 인터셉터 클레스를 구현 후, @EnableWebMvc ,implements WebMvcConfigurer 가 구현되어 있는 클레스에서 간단하게 사용이 가능합니다.

@Configuration
@ComponentScan(basePackages = {"du"})
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer{

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new FirstInterceptor());
    }
}

 

이렇게 등록을 하게되면 DispatcherServlet으로 들어온 요청은, Interceptor를 거치며, 해당 메서드들의 기능을 수행하게 됩니다. 

 

하지만 보통 개발을 하다보면 하나이상의 Interceptor를 사용하는 경우가 많으며, 이 사이에 순서가 매우 중요할 수 있습니다. 이경우 addInterceptor 를 하면 어떻게 되는지 보겠습니다.

 

위에와 동일한 SecondIntercepter 를 생성하고, 각 메서드별로 출력을 해보겠습니다.

우선.. 바로 위에있는 registry.addInterceptor(new FirstInterceptor()); 아래에 registry.addInterceptor(new SecondInterceptor());를 추가한 결과입니다.

 

별다른 order 설정을 하지않으면 먼저 등록된 Interceptor가 우선 순위가 높아지며 

Interceptor 1 ( preHandle)

Interceptor 2 ( preHandle)

 

Interceptor 2 ( postHandle)

Interceptor 1 ( postHandle)

 

Interceptor 1 ( afterCompletion)

Interceptor 2 ( afterCompletion)

순으로 실행이 됩니다. 

 

 

만약 별도로 우선순위를 설정하시고 싶다면 코드에 해당 작업을 할 수 있습니다.

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new FirstInterceptor()).order(-1);
        registry.addInterceptor(new SecondInterceptor()).order(-2);
    }

 

order외에도 pathMatcher ,excludePathPatterns 등 요청별로 인터셉터를 구분할수도 있습니다.

 

 

계속 사용하는 Interceptor에 대해서 간략하게나마 정리를 하고 넘어가는 시간이였습니다.

728x90
Comments