Feign調(diào)用中的兩種Header傳參方式小結(jié)
Feign調(diào)用中的兩種Header傳參方式
在Spring Cloud Netflix棧中,各個微服務(wù)都是以HTTP接口的形式暴露自身服務(wù)的,因此在調(diào)用遠程服務(wù)時就必須使用HTTP客戶端。
我們可以使用JDK原生的URLConnection、Apache的Http Client、Netty的異步HTTP Client, Spring的RestTemplate。公司目前使用的是Feign。
下面來和大家一起學(xué)習(xí)下feign調(diào)用中兩種Header傳參方式。
在請求攔截器中統(tǒng)一配置
每次Feign調(diào)用中,需要傳遞一些安全校驗參數(shù),比如說token,bizId啥的,如果單獨在每次調(diào)用的時候去配置這些重復(fù)的邏輯,顯然不合適。所以我們可以在Feign的攔截器中統(tǒng)一配置這些權(quán)限參數(shù)。
如何配置呢?其實很簡單。
import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import feign.RequestInterceptor; import feign.RequestTemplate; import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; ? @Configuration public class FeignConfiguration implements RequestInterceptor { ? ? @Override ? ? public void apply(RequestTemplate template) { ? ? ? ? ServletRequestAttributes attributes = (ServletRequestAttributes) ? ? ? ? ? ? ? ? RequestContextHolder.getRequestAttributes(); ? ? ? ? HttpServletRequest request = attributes.getRequest(); ? ? ? ? Enumeration<String> headerNames = request.getHeaderNames(); ? ? ? ? if (headerNames != null) { ? ? ? ? ? ? while (headerNames.hasMoreElements()) { ? ? ? ? ? ? ? ? String name = headerNames.nextElement(); ? ? ? ? ? ? ? ? String values = request.getHeader(name); ? ? ? ? ? ? ? ? template.header(name, values); ? ? ? ? ? ? } ? ? ? ? } ? ? } }
然后再feignClient中配置自定義的配置類,覆蓋默認的配置
@Component @FeignClient(value = "feignTest" ,configuration = FeignConfiguration.class) public interface FeignTestService { }
這樣就所有的Feign調(diào)用都會在Header調(diào)用中加上request中傳遞過來的參數(shù)。不需要單獨在每次Feign調(diào)用重復(fù)添加參數(shù)。
通過@RequestHeader注解
上面也說到,我們在攔截器中獲取request傳遞過來的參數(shù),然后再放到header中。在攔截器中配置的一般都是公用的一些參數(shù)。
但是如果一個服務(wù)接口,需要一些特殊參數(shù)。但是其他服務(wù)不需要這個參數(shù),這時候我們不必在攔截器中配置其他服務(wù)不需要的參數(shù),只需在需要的服務(wù)接口上加上@RequestHeader注解,然后在feign調(diào)用的時候把參數(shù)傳過來就ok了。
@PostMapping(value = "/orderDetails") public ReturnInfo getOrderDetail(@RequestHeader(name = "id") String orderId);
比如說之前在quartz中通過Feign調(diào)用其他服務(wù)獲取優(yōu)惠券信息,項目中封裝的方法獲取的attributes 是空的。
ServletRequestAttributes attributes = (ServletRequestAttributes) ? ? ? ? ? ? ? ? RequestContextHolder.getRequestAttributes();
這時候就不用攔截器了,直接在方法入?yún)⑸霞由?@RequestHeader注解。
這里簡單介紹下Feign調(diào)用的傳參,實際在項目中,大家對Feign調(diào)用方法都有自己的封裝,代碼和上面的可能不一樣,但是原理都是差不多的。
調(diào)用feign接口時,如何往header中添加參數(shù)
Controller接收到請求后,我們可以在service中通過feign直接調(diào)用其它服務(wù)的接口,但是,controller接收到的請求和通過feign調(diào)用其它服務(wù),其它服務(wù)接收到的請求,是不一樣的。例如我們往往習(xí)慣于在header中放入用戶的token信息,在不做處理的情況下,其它服務(wù)接收到的請求,可能就是無用戶信息狀態(tài),這種請求應(yīng)該判定為無效狀態(tài)。
在服務(wù)的提供方或者調(diào)用方定義一個攔截器,將當前請求的token信息手動添加到feign請求的header中。
@Configuration public class FeignRequestInterceptorConfig implements RequestInterceptor { @Bean public RequestContextListener requestContextListener() { return new RequestContextListener(); } @Override public void apply(RequestTemplate requestTemplate) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (ObjectUtils.isEmpty(attributes)) { return; } HttpServletRequest request = attributes.getRequest(); String token = request.getHeader("token"); requestTemplate.header("token", token); } }
在使用過程中,可能會涉及到在請求方獲取自己的token信息都是為空的,查看一下是否是Hystrix策略導(dǎo)致的,如下配置可以解決該問題。
hystrix: command: default: execution: timeout: #如果enabled設(shè)置為false,則請求超時交給ribbon控制 enabled: true isolation: # 隔離策略 strategy: SEMAPHORE thread: timeoutInMilliseconds: 100000
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺談Java中Collection和Collections的區(qū)別
下面小編就為大家?guī)硪黄獪\談Java中Collection和Collections的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08SpringBoot整合Druid實現(xiàn)SQL監(jiān)控和數(shù)據(jù)庫密碼加密
Druid連接池是阿里巴巴開源的數(shù)據(jù)庫連接池項目,Druid連接池為監(jiān)控而生,內(nèi)置強大的監(jiān)控功能,監(jiān)控特性不影響性能,本文給大家介紹了SpringBoot整合Druid實現(xiàn)SQL監(jiān)控和數(shù)據(jù)庫密碼加密,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2024-06-06SpringBoot實現(xiàn)文件上傳下載功能小結(jié)
最近做的一個項目涉及到文件上傳與下載功能。SpringBoot后臺如何實現(xiàn)文件上傳下載呢?下面有單文件上傳和多文件上傳功能,感興趣的朋友一起看看吧2017-08-08解決spring 處理request.getInputStream()輸入流只能讀取一次問題
這篇文章主要介紹了解決spring 處理request.getInputStream()輸入流只能讀取一次問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09淺談springfox-swagger原理解析與使用過程中遇到的坑
本篇文章主要介紹了淺談springfox-swagger原理解析與使用過程中遇到的坑,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02