一,OpenFeign遠端調用丢失請求頭問題

原理
下面是OpenFeign遠端調用的方法的源碼部分,可以看到,是Spring調用buildTemplateFromArgs.create(argv)方法,建構了一個新的請求,這個請求沒有任何的請求頭資訊,也就是我們請求頭的資料會丢失.
但是,我們看到,在建構這個新請求的時候,會進入到executeAndDecode(template, options)方法,進入到這個方法以後,我們看到,繼續調用調用Request request = targetRequest(template)對請求做了處理,
可以看到,周遊我們所有的攔截器Interceptor,給構造的請求附加參數,是以,給我們的容器中加上一個攔截器Interceptor就可以解決請求頭丢失問題,代碼如下
@Configuration
public class NaisiFeignConfig {
@Bean
public RequestInterceptor requestInterceptor(){
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
//2,RequestContextHolder拿到剛進來的這個請求
//RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
System.out.println("RequestInterceptor線程"+Thread.currentThread().getId());
//老請求
//空指針Exception
HttpServletRequest request = requestAttributes.getRequest();
if (request != null){
//同步請求頭資料,Cookie
String cookie = request.getHeader("Cookie");
//給新請求同步了老請求的Cookie
template.header("Cookie",cookie);
}
}
};
}
}
這時,新請求一進來就會先調用我們的攔截器,我們在攔截器給請求設定上所需要的Header請求頭資訊就可以.
二,異步調用丢失上下文問題
上面是OpenFeign遠端調用丢失請求頭問題,此時,我們發現,如果是異步請求,我們的攔截器就不能設定上所需要的Header資訊.
原因
因為我們是異步請求,請求不一樣
這裡是使用ThreadLocal,即可以拿到同一個線程攜帶的資料,但是不同線程的資料,我們是拿不到的,
解決方法
我們在發遠端調用請求之前,給異步請求添加上上下文資訊即可
//擷取之前的請求
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//1,遠端查詢所有的收貨位址清單
CompletableFuture<Void> getAddress = CompletableFuture.runAsync(() -> {
System.out.println("address線程"+Thread.currentThread().getId());
//每一個線程都來共享之前請求的資料
RequestContextHolder.setRequestAttributes(requestAttributes);
List<MemberAddressVo> address = memberFeignService.getAddress(memberRespVo.getId());
confirmVo.setAddress(address);
}, executor);
此時就可以解決上下文丢失問題