亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

如何在Spring WebFlux的任何地方獲取Request對象

瀏覽:89日期:2023-07-25 11:51:14
1 不一樣的世界

在常規(guī)的Spring Web項目中,我們要獲取Request對象是非常方便的,不少庫都提供了靜態(tài)方法來獲取。獲取代碼如下:

ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();// get the requestHttpServletRequest request = requestAttributes.getRequest();

在類RequestContextHolder提供了靜態(tài)方法,也就意味著你可以在任何地方調用。而它使用了ThreadLocal來保存Request對象,也就是不同線程是可以獲取各自的Request對象。

但在響應式WebFlux的世界里,并沒有提供類似的Holder類,而WebFlux是無法感知線程的,任何一個線程可以在任何時候處理任何請求,如果它覺得切換當前線程更有效率,它就會這么做。但在Servlet Based的應用里,它會為某個請求安排一個線程去處理完整個過程。

這個巨大的差別,意味著不能簡單地通過ThreadLocal來保存和獲取Request了。

2 先保存,再獲取

為了在后面可以方便獲得Request對象,我們就需要在開始的時候把它存在一個可以使用、并且是相同scope的容器里。這里需要解決兩個關鍵問題:

(1)Request對象從何而來;

(2)存在哪里?

針對問題(1), 我們可以回想什么時候會出現Request對象,最容易想得到的就是WebFilter了,它的方法簽名如下:

public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain);

我們可以通過ServerWebExchange直接獲取到Request對象:

ServerHttpRequest request = exchange.getRequest();

而因為Filter是可以先于應用邏輯執(zhí)行的,所以滿足要求,問題(1)解決。

針對問題(2),需要一個與Reavtive請求相同范圍的容器,reactor.util.context.Context可以滿足需求。查看reactor的官方文檔(https://projectreactor.io/docs/core/release/reference/#context )可見下面這段話:

Since version 3.1.0, Reactor comes with an advanced feature that is somewhat comparable to ThreadLocal but can be applied to a Flux or a Mono instead of a Thread. This feature is called Context.

并且官網也給出了為何ThreadLocal在某些場景不適用的解釋,有興趣可以看看。

3 代碼實現3.1 WebFilter獲取并保存

首先,在WebFilter中獲取Request對象并保存,代碼如下:

@Configuration@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)public class ReactiveRequestContextFilter implements WebFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); return chain.filter(exchange).subscriberContext(ctx -> ctx.put(ReactiveRequestContextHolder.CONTEXT_KEY, request)); }}

從ServerWebExchange中獲取到ServerHttpRequest對象,再通過put方法把它放進Context里。

3.2 工具類Holder

實現一個工具類來提供靜態(tài)方法,在Filter后的任何場景都可以使用:

public class ReactiveRequestContextHolder { public static final Class<ServerHttpRequest> CONTEXT_KEY = ServerHttpRequest.class; public static Mono<ServerHttpRequest> getRequest() { return Mono.subscriberContext().map(ctx -> ctx.get(CONTEXT_KEY)); }}3.3 在Controller中使用

我們嘗試在Controller中使用ReactiveRequestContextHolder來獲取Request:

@RestControllerpublic class GetRequestController { @RequestMapping('/request') public Mono<String> getRequest() { return ReactiveRequestContextHolder.getRequest().map(request -> request.getHeaders().getFirst('user')); }}

上面方法獲取了Request對象,然后再獲取了Request中的Header。

啟動應用,測試如下:

$ curl http://localhost:8088/request -H ’user: pkslow’pkslow$ curl http://localhost:8088/request -H ’user: larry’larry$ curl http://localhost:8088/request -H ’user: www.pkslow.com’www.pkslow.com

可以成功獲取請求頭user。

4 總結

代碼請查看:https://github.com/LarryDpk/pkslow-samples

以上就是如何在Spring WebFlux的任何地方獲取Request對象的詳細內容,更多關于Spring WebFlux獲取Request對象的資料請關注好吧啦網其它相關文章!

標簽: Spring
相關文章:
主站蜘蛛池模板: 被公侵犯肉体中文字幕一区二区 | 国产成人亚洲精品一区二区在线看 | 亚洲福利视频一区 | 国产精品美女www爽爽爽视频 | a一级爱做片免费 | 国产日韩一区二区三区 | 国产黄色在线视频 | 亚洲步兵一区二区三区 | 91寡妇天天综合久久影院 | 中文字幕久久综合 | 欧美日韩另类在线 | 色噜噜狠狠一区二区三区 | 97视频精品| 美国老黑一级毛片免费的大黄 | 欧美 亚洲 国产 精品有声 | 欧美啪啪精品 | 国产一级片观看 | 免费可在线观看黄的视频 | 日本在线精品视频 | 久久香蕉国产在产线看观看 | xxxxx做受大片视频免费 | 毛片毛片毛片毛片毛片毛片毛片 | 婷婷色综合久久五月亚洲 | 成人午夜影视全部免费看 | 欧美日本一区亚洲欧美一区 | 人人婷婷色综合五月第四人色阁 | 国产一区二区三区精品视频 | 国产第一页在线播放 | 日韩免费观看 | 亚洲国产成人资源在线桃色 | 99热在线获取最新地址 | 欧美成人免费全部观看在线看 | 毛片女人毛片一级毛片毛片 | 97视频免费公开成人福利 | 免费的黄视频 | 婷婷黄色网 | 91香蕉小视频 | 欧美夜夜精品一级爽 | 精品香蕉伊思人在线观看 | 亚洲欧美精品国产一区色综合 | 国产日韩精品一区在线不卡 |