Spring

Spring, Kotlin - Interceptor

블린더르 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

반응형