Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- VictoriaMetrics
- ExecutableJar
- Vmalert
- Reassign
- raft
- kafka
- Rebalance
- Reactive
- Mirror
- OpenJDK
- tsdb
- API문서
- consumer
- springboot
- spring
- swagger
- java
- restdocs
- Zookeeper
- ProjectLoom
- JDK
- OFFSET
- Brooklin
- Vmagent
- broker
- NoClassDefFoundError
- JVM
- 비동기
- webflux
Archives
- Today
- Total
거북이 developer
Spring Webflux - Filter 본문
Filter
- Spring Webflux 에서는 MVC 의 Interceptor 와 비슷한 역할을 하는 HandlerFilterFunction 과 Servlet Filter 와 비슷한 역할을 하는 WebFilter Interface 를 제공하고 있다.
HandlerFilterFunction
- 핸들러 펑션에 필터를 적용할 땐 RouterFunction Builder 를 사용하면 되는데, 다음과 같은 함수가 있다.
- before : Handler 함수 수행 전에 동작하는 함수를 등록하며 인자로 Function<ServerRequest, ServerRequest> 를 받는다.
- after : Handler 함수가 수행 완료되면 동작하는 함수를 등록하며 인자로 BiFunction<ServerRequest, ServerResponse, ServerResponse> 를 받는다.
- filter : 인자로 HandlerFilterFunction<ServerRequest, ServerResponse> 를 받으며, 필터를 어떻게 수행하고 다음 handler function 을 어떻게 호출할지의 일련의 동작을 모두 구현할 수 있다.
- 필터는 빌더의 모든 라우터 펑션에 적용된다. 이 말은 필터를 감싸져 있는 라우터에서 정의하면, 상위 레벨에는 적용되지 않는다는 뜻이다.
RouterFunction<ServerResponse> route = RouterFunctions.route()
.path("/person", b1 -> b1
.nest(RequestPredicates.accept(APPLICATION_JSON), b2 -> b2
.GET("/{id}", handler::getPerson)
.GET("", handler::listPeople)
.before(request -> ServerRequest.from(request) // (1)
.header("X-RequestHeader", "Value")
.build()))
.POST("/person", handler::createPerson))
.after((request, response) -> logResponse(response)) // (2)
.build();
(1) X-RequestHeader 를 추가하는 filter 는 두 GET Router 에만 적용되며 Router 실행 전에 수행된다.
(2) response 를 logging 하는 filter 는 모든 Router 에 적용되며 Router 실행 후 수행된다.
- filter 메소드는 HandlerFilterFunction을 인자로 받는다. 이 인터페이스는 ServerRequest, HandlerFunction을 받아 ServerResponse를 리턴하는 함수다. 두번째 인자로 받는 HandlerFunction 파라미터는 체인에 있는 다음 HandlerFunction 이다. 보통 이 HandlerFunction 은 라우팅할 핸들러지만, HandlerFilterFunction 이 여러 개가 등록되어있다면 HandlerFilterFunction 일 수도 있다.
- path를 보고 요청을 허가할지 말지 결정하는 SecurityManager가 있다고 가정하고, filter 함수를 통해 보안 필터를 라우터에 적용해 보면 다음과 같다.
SecurityManager securityManager = ...
RouterFunction<ServerResponse> route = RouterFunctions.route()
.path("/person", b1 -> b1
.nest(RequestPredicates.accept(APPLICATION_JSON), b2 -> b2
.GET("/{id}", handler::getPerson)
.GET("", handler::listPeople))
.POST("/person", handler::createPerson))
.filter((request, next) -> {
if (securityManager.allowAccessTo(request.path())) {
return next.handle(request);
}
else {
return ServerResponse.status(UNAUTHORIZED).build();
}
})
.build();
위 예제를 보면 next.handle(ServerRequest) 호출은 선택이라는 점을 알 수 있다. 여기선 접근을 허가할 때만 실행했다.
⚠️ filter 를 구현하다보면 Request 객체에 attribute 나 header 등의 값을 주입하거나 변경해야할 때가 있는데, 그럴 때 ServerRequest.Builder 나 혹은 Builder 를 사용하는 API(from) 로 ServerRequest 를 새로 생성하여 변경할 경우 다음 HandlerFunction 에서 request body 를 가져올 수 없다. 반드시 주입받은 ServerRequest 를 다음 HandlerFunction 에 넘겨주도록 구현해야 한다.
WebFilter
- WebFilter 를 구현하여 Bean 으로 등록(혹은 @Component Annotation 을 등록)하면 WebFilter 를 사용할 수 있다.
- WebFilter 는 여러개가 등록 가능하며 순서를 맞추고자 한다면 @Order 를 사용한다.
- 아래는 Spring Webflux 에서 HttpHandler, ExceptionHandler, WebFlilter, DispatcherHandler 간의 동작 과정이다. FilteringWebHandler 부터 DefaultWebFilterChain 까지가 WebFilter 의 동작 부분이라 볼 수 있으며 Bean(혹은 @Component Annotation)으로 등록한 WebFliter 는 DefaultWebFilterChain 안에서 동작하게 된다.
⚠️ HandlerFilterFunction 은 위 동작에 포함되지 않으며 DispatcherHandler 수행시 동작하게 된다.
- 인증, ACL, Access Logging 과 같이 요청시 우선적으로 실행해야 하거나 HandlerFilterFunction 에 영향을 받지 않도록 하려면 WebFilter 를 구현하여 사용하는게 좋다.
- Spring Webflux 에서 제공하는 대표적인 WebFilter 로 CorsFilter 가 있다.
'Spring Framework' 카테고리의 다른 글
Spring Webflux - Server Configuration (0) | 2022.03.14 |
---|---|
Spring Webflux - WebClient (0) | 2022.03.14 |
Spring Webflux - HandlerFunction (0) | 2022.03.14 |
Spring Webflux - Request Mapping (0) | 2022.03.14 |
Spring Webflux - Overview (0) | 2022.03.14 |
Comments