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
|
@Beanfun 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, являются их собственными. |