ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring, Kotlin - Interceptor
    Spring 2021. 11. 25. 23:52

    특정 Request 에 특정 기능을 적용하려는 경우에 Interceptor 를 사용할 수 있습니다.

    Request 를 가로채서(intercept) 실제 처리 이전, 이후의 작업을 추가할 수 있습니다.

    Method 설명
    preHandle 실제 처리 부분 이전 작업
    postHandle 실제 처리 부분 이후 작업
    afterCompletion 전체 요청이 완료된 후 작업

    Request 의 Log 를 찍어주는 Interceptor 를 생성하고 테스트를 통해 확인해보겠습니다.

    Spring Boot 2.6.0, Kotlin 1.6 버전을 사용하였습니다.

    class LogInterceptor : HandlerInterceptor {
        companion object {
            val log = LoggerFactory.getLogger(this::class.java)
        }
    
        override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
            log.info("[preHandle][${request}] : [${request.method}] ${request.requestURI}")
            return true
        }
    
        override fun postHandle(
            request: HttpServletRequest,
            response: HttpServletResponse,
            handler: Any,
            modelAndView: ModelAndView?
        ) {
            log.info("[postHandle][$request]")
        }
    
        override fun afterCompletion(
            request: HttpServletRequest,
            response: HttpServletResponse,
            handler: Any,
            ex: Exception?
        ) {
            log.info("[afterCompletion][request]")
        }
    }

    WebConfig 를 생성하여 InterceptorInterceptorRegistry 에 추가합니다.

    @Configuration
    class WebConfig : WebMvcConfigurer {
        override fun addInterceptors(registry: InterceptorRegistry) {
            registry.addInterceptor(LogInterceptor())
        }
    }

    그 후 테스트용으로 사용할 간단한 Controller 를 생성합니다.

    @RestController
    @RequestMapping("test")
    class TestController {
        companion object{
            private val log = LoggerFactory.getLogger(this::class.java)
        }
    
        @GetMapping
        fun interceptorTest(){
            log.info("실제 처리 부분")
        }
    }
    @WebMvcTest(TestController::class)
    @TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
    internal class TestControllerTest(
        private val mockMvc: MockMvc
    ) {
    
        @Test
        fun interceptorTest() {
            mockMvc.get("/test")
        }
    }

    위의 테스트를 실행하게 되면 아래와 같은 결과를 확인할 수 있습니다.

    INFO 33531 --- [    Test worker] m.c.i.LogInterceptor$Companion           : [preHandle][org.springframework.mock.web.MockHttpServletRequest@4ed18798] : [GET] /test
    INFO 33531 --- [    Test worker] m.c.i.c.TestController$Companion         : 실제 처리 부분
    INFO 33531 --- [    Test worker] m.c.i.LogInterceptor$Companion           : [postHandle][org.springframework.mock.web.MockHttpServletRequest@4ed18798]
    INFO 33531 --- [    Test worker] m.c.i.LogInterceptor$Companion           : [afterCompletion][request]

    실제 처리 부분 전후로 Interceptor 가 로그를 찍어준 것을 확인할 수 있습니다.

    InterceptorRegistry 에 Interceptor 를 추가할 때 적용할 경로, 예외 경로를 지정할 수 있습니다.

    @Configuration
    class WebConfig : WebMvcConfigurer {
        override fun addInterceptors(registry: InterceptorRegistry) {
            registry.addInterceptor(LogInterceptor())
                .addPathPatterns("/test")
                .excludePathPatterns("/test/exclude")
        }
    }

    addPathPatternsexcludePathPatterns 으로 Interceptor 가 작동할 경로와 예외로할 경로를 지정할 수 있습니다.

    코드

    https://github.com/sinna94/blog-source

    참고

    mvc-handlermapping-interceptor

    mvc-config-interceptors

    https://www.baeldung.com/spring-mvc-handlerinterceptor

    반응형

    댓글 0

Designed by Tistory.