OpenFeign實(shí)現(xiàn)攜帶請(qǐng)求頭方案詳細(xì)介紹
在使用OpenFeign請(qǐng)求其他服務(wù)接口時(shí),默認(rèn)不攜帶header信息,這樣就導(dǎo)致無(wú)法攜帶登錄用戶(hù)信息。要解決這個(gè)問(wèn)題,下面分兩種情況進(jìn)行處理。
1. 同步請(qǐng)求
對(duì)于同步請(qǐng)求,無(wú)需另作處理,只需從header中獲取token信息,放入新請(qǐng)求即可。
@Configuration public class FeignConfig { @Bean public RequestInterceptor requestInterceptor(){ return new RequestInterceptor() { @Override public void apply(RequestTemplate requestTemplate) { ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if(requestAttributes != null){ //獲取請(qǐng)求的token信息 String token = requestAttributes.getRequest().getHeader(BaseConstant.TOKEN_HEADER); //同步到請(qǐng)求中 requestTemplate.header(BaseConstant.TOKEN_HEADER,token); return; } } }; } }
2. 異步請(qǐng)求
對(duì)于異步請(qǐng)求(例如A線(xiàn)程接到了HTTP請(qǐng)求,然后開(kāi)啟子線(xiàn)程B,B處理完成后調(diào)用openfeign接口),是無(wú)法使用上述方法的。因?yàn)镽equestContextHolder.getRequestAttributes()方法獲取的requestAttributesHolder變量,是ThreadLocal類(lèi)型的:
private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal("Request attributes");
所以想到了一個(gè)簡(jiǎn)單的辦法,在創(chuàng)建子線(xiàn)程時(shí),將當(dāng)前線(xiàn)程的token信息傳遞到子線(xiàn)程中。子線(xiàn)程在調(diào)用feign接口前,將token存入當(dāng)前線(xiàn)程變量中,token類(lèi)定義以及ThreadLocal定義如下:
//Token類(lèi)定義 @Data public class TokenInfo implements Serializable { private String token; } //TokenContext類(lèi)定義 public class TokenContext { public static final ThreadLocal<TokenInfo> tokenInfo = new ThreadLocal<>(); //設(shè)置token信息 public static void set(TokenInfo info){ tokenInfo.set(info); } //獲取token信息 public static TokenInfo get(){ return tokenInfo.get(); } //移除token信息 public static void remove(){ tokenInfo.remove(); } }
調(diào)用接口處理:
TokenInfo info = new TokenInfo(); info.setToken(token); TokenContext.set(info); //調(diào)用接口 feign.interface; //一定要記得刪除,不然后內(nèi)存泄露風(fēng)險(xiǎn) TokenContext.remove();
最后,上述創(chuàng)建的Bean改為:
@Configuration public class FeignConfig { @Bean public RequestInterceptor requestInterceptor(){ return new RequestInterceptor() { @Override public void apply(RequestTemplate requestTemplate) { //老請(qǐng)求 獲取當(dāng)前線(xiàn)程請(qǐng)求的請(qǐng)求信息 ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if(requestAttributes != null){ String token = requestAttributes.getRequest().getHeader(BaseConstant.TOKEN_HEADER); //同步到請(qǐng)求中 requestTemplate.header(BaseConstant.TOKEN_HEADER,token); return; } TokenInfo tokenInfo = TokenContext.get(); if(userInfo != null){ String token = tokenInfo.getToken(); requestTemplate.header(BaseConstant.TOKEN_HEADER,BaseConstant.TOKEN_PREFIX + token); return; } } }; } }
到此這篇關(guān)于OpenFeign實(shí)現(xiàn)攜帶請(qǐng)求頭方案詳細(xì)介紹的文章就介紹到這了,更多相關(guān)OpenFeign攜帶請(qǐng)求頭內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Jenkins+Maven+Gitea+Nexus搭建CICD環(huán)境的方式
這篇文章主要介紹了基于Jenkins+Maven+Gitea+Nexus從0到1搭建CICD環(huán)境,大家都知道Nexus是一套“開(kāi)箱即用”的系統(tǒng)不需要數(shù)據(jù)庫(kù),它使用文件系統(tǒng)加Lucene來(lái)組織數(shù)據(jù),需要的朋友可以參考下2022-01-01淺析Spring Security登錄驗(yàn)證流程源碼
這篇文章主要介紹了Spring Security登錄驗(yàn)證流程源碼解析,本文結(jié)合源碼講解登錄驗(yàn)證流程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11springcloud整合gateway實(shí)現(xiàn)網(wǎng)關(guān)全局過(guò)濾器功能
本文主要介紹了springcloud整合gateway實(shí)現(xiàn)網(wǎng)關(guān)全局過(guò)濾器功能,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02深入了解Java語(yǔ)言中的并發(fā)性選項(xiàng)有何不同
這篇文章主要介紹了深入了解Java語(yǔ)言中的并發(fā)性選項(xiàng)有何不同,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下2019-06-06mybatis快速入門(mén)學(xué)習(xí)教程新手注意問(wèn)題小結(jié)
MyBatis 是支持定制化 SQL、存儲(chǔ)過(guò)程以及高級(jí)映射的優(yōu)秀的持久層框架。接下來(lái)通過(guò)本文給大家介紹mybatis快速入門(mén)學(xué)習(xí)教程新手注意問(wèn)題小結(jié),需要的朋友可以參考下2017-02-02