Feign調(diào)用中的兩種Header傳參方式小結(jié)
Feign調(diào)用中的兩種Header傳參方式
在Spring Cloud Netflix棧中,各個微服務都是以HTTP接口的形式暴露自身服務的,因此在調(diào)用遠程服務時就必須使用HTTP客戶端。
我們可以使用JDK原生的URLConnection、Apache的Http Client、Netty的異步HTTP Client, Spring的RestTemplate。公司目前使用的是Feign。
下面來和大家一起學習下feign調(diào)用中兩種Header傳參方式。
在請求攔截器中統(tǒng)一配置
每次Feign調(diào)用中,需要傳遞一些安全校驗參數(shù),比如說token,bizId啥的,如果單獨在每次調(diào)用的時候去配置這些重復的邏輯,顯然不合適。所以我們可以在Feign的攔截器中統(tǒng)一配置這些權限參數(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)用重復添加參數(shù)。
通過@RequestHeader注解
上面也說到,我們在攔截器中獲取request傳遞過來的參數(shù),然后再放到header中。在攔截器中配置的一般都是公用的一些參數(shù)。
但是如果一個服務接口,需要一些特殊參數(shù)。但是其他服務不需要這個參數(shù),這時候我們不必在攔截器中配置其他服務不需要的參數(shù),只需在需要的服務接口上加上@RequestHeader注解,然后在feign調(diào)用的時候把參數(shù)傳過來就ok了。
@PostMapping(value = "/orderDetails") public ReturnInfo getOrderDetail(@RequestHeader(name = "id") String orderId);
比如說之前在quartz中通過Feign調(diào)用其他服務獲取優(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)用其它服務的接口,但是,controller接收到的請求和通過feign調(diào)用其它服務,其它服務接收到的請求,是不一樣的。例如我們往往習慣于在header中放入用戶的token信息,在不做處理的情況下,其它服務接收到的請求,可能就是無用戶信息狀態(tài),這種請求應該判定為無效狀態(tài)。
在服務的提供方或者調(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策略導致的,如下配置可以解決該問題。
hystrix:
command:
default:
execution:
timeout:
#如果enabled設置為false,則請求超時交給ribbon控制
enabled: true
isolation:
# 隔離策略
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 100000
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
淺談Java中Collection和Collections的區(qū)別
下面小編就為大家?guī)硪黄獪\談Java中Collection和Collections的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08
SpringBoot整合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ù)庫密碼加密,文中有相關的代碼示例供大家參考,需要的朋友可以參考下2024-06-06
SpringBoot實現(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

