Spring Webflux — это новый реактивный веб-фреймворк, доступный как часть Spring 5+. То, как фильтры были написаны в традиционном приложении на основе Spring MVC ( Servlet Filter , HandlerInterceptor ), сильно отличается от того, как фильтр пишется в приложении на основе Spring Webflux, и в этом посте кратко рассмотрим подход WebFlux к фильтрам.
Подход 1 — WebFilter
Первый подход с использованием WebFilter затрагивает все конечные точки в целом и охватывает конечные точки Webflux, написанные в функциональном стиле, а также конечные точки, написанные с использованием стиля аннотаций . WebFilter в Котлине выглядит так:
1
2
3
4
5
6
7
8
9
|
@Bean fun sampleWebFilter(): WebFilter { return WebFilter { e: ServerWebExchange, c: WebFilterChain -> val l: MutableList<String> = e.getAttributeOrDefault(KEY, mutableListOf()) l.add( "From WebFilter" ) e.attributes.put(KEY, l) c.filter(e) } } |
WebFilter добавляет атрибут запроса со значением, представляющим собой коллекцию, в которой фильтр просто помещает сообщение о том, что он перехватил запрос.
Подход 2 — HandlerFilterFunction
Второй подход более сфокусирован и охватывает только конечные точки, написанные с использованием функционального стиля . Здесь определенные функции RouterFunctions можно подключить с помощью фильтра, как показано ниже:
Рассмотрим конечную точку Spring Webflux, определенную следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
|
@Bean fun route(): RouterFunction<*> = router { GET( "/react/hello" , { r -> ok().body(fromObject( Greeting( "${r.attribute(KEY).orElse(" [Fallback]: ")}: Hello" ) )) POST( "/another/endpoint" , TODO()) PUT( "/another/endpoint" , TODO()) }) } |
Функция HandlerFilterFunction, которая перехватывает только эти API, может быть добавлена с высокой степенью фокусировки следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
fun route(): RouterFunction<*> = router { GET( "/react/hello" , { r -> ok().body(fromObject( Greeting( "${r.attribute(KEY).orElse(" [Fallback]: ")}: Hello" ) )) }) POST( "/another/endpoint" , TODO()) PUT( "/another/endpoint" , TODO()) }.filter({ r: ServerRequest, n: HandlerFunction<ServerResponse> -> val greetings: MutableList<String> = r.attribute(KEY) .map { v -> v as MutableList<String> }.orElse(mutableListOf()) greetings.add( "From HandlerFilterFunction" ) r.attributes().put(KEY, greetings) n.handle(r) }) |
Обратите внимание, что нет необходимости быть явным о типах в Kotlin, я добавил это просто для ясности о типах в некоторых лямбда-выражениях
Вывод
Подход WebFilter и функция HandlerFilterFunction сильно отличаются от подхода, основанного на Spring WebMVC, при написании фильтров с использованием спецификаций сервлета или с помощью HandlerInterceptors, и в этом посте кратко изложены новые подходы — в моем git- репозитории есть примеры, которые рассматриваются более подробно.
Смотрите оригинальную статью здесь: Spring Webflux — Написание фильтров
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |