微服务-Feign客户端服务之间传递token
2018-06-22 本文已影响115人
martin6699
我们使用Spring Cloud 服务间互调,使用Feign声明式服务客户端调用实现。那如何在feign客户端间或feign客户端与server服务端传递token呢?
答案是可以使用Feign拦截器,我使用的版本是Spring Cloud Openfeign 2.0.0.M2
,话不多说,上代码
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import javax.servlet.http.HttpServletRequest;
import feign.RequestInterceptor;
import feign.RequestTemplate;
@Configuration // 加上该注解 ,则不需要FeignClient里面加属性configuration
public class FeignHeadersInterceptor implements RequestInterceptor {
@Override public void apply(RequestTemplate template) {
HttpServletRequest request = getHttpServletRequest();
if (Objects.isNull(request)) {
return;
}
Map<String, String> headers = getHeaders(request);
if (headers.size() > 0) {
Iterator<Entry<String, String>> iterator = headers.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, String> entry = iterator.next();
// 把请求过来的header请求头 原样设置到feign请求头中
// 包括token
template.header(entry.getKey(), entry.getValue());
}
}
}
private HttpServletRequest getHttpServletRequest() {
try {
// 这种方式获取的HttpServletRequest是线程安全的
return ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
} catch (Exception e) {
return null;
}
}
private Map<String, String> getHeaders(HttpServletRequest request) {
Map<String, String> map = new LinkedHashMap<>();
Enumeration<String> enums = request.getHeaderNames();
while (enums.hasMoreElements()) {
String key = enums.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
return map;
}
}
上述代码中,getHttpServletRequest方法获取Request请求,而getHeaders从Request中拿到请求头信息,最后设置到RequestTemplate的headers中,而RequestTemplate就相当于feign客户端的HttpClient。