在構(gòu)建微服務(wù)架構(gòu)時(shí),Spring Cloud Gateway作為一個(gè)重要的微服務(wù)網(wǎng)關(guān),經(jīng)常需要在過(guò)濾器(Filter)中對(duì)POST請(qǐng)求的Body內(nèi)容進(jìn)行操作,如日志記錄、簽名驗(yàn)證和權(quán)限驗(yàn)證等。然而,由于Request的Body只能讀取一次,如果直接在過(guò)濾器中讀取而不進(jìn)行封裝,可能導(dǎo)致后續(xù)服務(wù)無(wú)法獲取數(shù)據(jù)。
網(wǎng)上搜這個(gè)問(wèn)題的解決方案,大多數(shù)文章都是告訴你寫一個(gè)Filter將Request的Body緩存起來(lái)。這種方法確實(shí)可以,只不過(guò)需要對(duì)代碼經(jīng)過(guò)充分壓力測(cè)試,否則很有可能出現(xiàn)如下所示的堆外內(nèi)存溢出問(wèn)題。
reactorty.ReactorNetty$InternalNettyException: ioty.util.internal.OutOfDirectMemoryError:failed to allocate
實(shí)際上,Spring Cloud Gateway已經(jīng)內(nèi)置了AdaptCachedBodyGlobalFilter過(guò)濾器,它在Exchange中巧妙地緩存了Request的Body,避免了直接讀取導(dǎo)致的一系列問(wèn)題。這種方式更為穩(wěn)妥,避免了潛在的內(nèi)存溢出風(fēng)險(xiǎn)。
圖片
在需要獲取Body的地方,我們只需要通過(guò)以下方法即可:
DataBuffer body = exchange.getAttributeOrDefault("cachedRequestBody", null);String bodyStr = body.toString(StandardCharsets.UTF_8);
只不過(guò)通過(guò)源碼可以看出,緩存RequestBody需要路由被標(biāo)記為需要緩存,也就是this.routesToCache.containsKey(rouceId)方法必須返回true。
AdaptCachedBodyGlobalFilter會(huì)監(jiān)聽EnableBodyCachingEvent事件,當(dāng)發(fā)布該事件時(shí)就將RouteId放入routesToCache中。為了方便使用,我們可以編寫一個(gè)配置類,在初始化時(shí)發(fā)布EnableBodyCachingEvent事件,將所有路由都啟用緩存功能。
@Configuration(proxyBeanMethods = false)@Slf4jpublic class EnableCachedBodyConfiguration { @Resource private ApplicationEventPublisher publisher; @Resource private GatewayProperties gatewayProperties; @PostConstruct public void init() { gatewayProperties.getRoutes().forEach(routeDefinition -> { // 對(duì) spring cloud gateway 路由配置中的每個(gè)路由都啟用 AdaptCachedBodyGlobalFilter EnableBodyCachingEvent enableBodyCachingEvent = new EnableBodyCachingEvent(new Object(), routeDefinition.getId()); publisher.publishEvent(enableBodyCachingEvent); }); }}
通過(guò)這種方式,我們可以更加方便地處理POST請(qǐng)求的Body內(nèi)容,避免了一些常見的問(wèn)題。在實(shí)際應(yīng)用中,考慮到穩(wěn)定性和性能,這種解決方案提供了一種更為可靠的選擇。
本文鏈接:http://www.www897cc.com/showinfo-26-34565-0.html徹底解決Spring Cloud Gateway中Body讀取問(wèn)題
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: 優(yōu)雅實(shí)現(xiàn)API接口開關(guān):讓你的應(yīng)用更可控
下一篇: Python爬蟲神器:Beautiful Soup指南,輕松解析網(wǎng)頁(yè)數(shù)據(jù)!