在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate。公司目前使用的是Feign。下面来和大家一起学习下feign调用中两种Header传参方式。

在请求拦截器中统一配置

每次Feign调用中,需要传递一些安全校验参数,比如说token,bizId啥的,如果单独在每次调用的时候去配置这些重复的逻辑,显然不合适。所以我们可以在Feign的拦截器中统一配置这些权限参数。如何配置呢?其实很简单。

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调用都会在Header调用中加上request中传递过来的参数。不需要单独在每次Feign调用重复添加参数。

通过@RequestHeader注解

上面也说到,我们在拦截器中获取request传递过来的参数,然后再放到header中。在拦截器中配置的一般都是公用的一些参数。但是如果一个服务接口,需要一些特殊参数。但是其他服务不需要这个参数,这时候我们不必在拦截器中配置其他服务不需要的参数,只需在需要的服务接口上加上@RequestHeader注解,然后在feign调用的时候把参数传过来就ok了。

@PostMapping(value = "/orderDetails")
public ReturnInfo getOrderDetail(@RequestHeader(name = "id") String orderId);

比如说之前在quartz中通过Feign调用其他服务获取优惠券信息,项目中封装的方法获取的attributes 是空的。

ServletRequestAttributes attributes = (ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes();

这时候就不用拦截器了,直接在方法入参上加上 @RequestHeader注解。

这里简单介绍下Feign调用的传参,实际在项目中,大家对Feign调用方法都有自己的封装,代码和上面的可能不一样,但是原理都是差不多的。

前言在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate。公司目前使用的是Feign。下面来和大家一起学习下feign调用中两种Hea...
feign调用方法: @RequestMapping(value = /resources/ocircuit/textInfo, method = {RequestMethod.GET}, produces = text/plain;charset=utf-8) String getOcircuitTextRouteInfo(@PathVariable(name = resID) String resID); 期望调用方法 @ApiOperation(value = 根据光路id查询光路的路由描述信息(局缆名称拼接)) @GetMapping(value = /resou
在使用springcloud经常会出现个服务调用,一般情况下会在Headers加上token的验证,那么在feign调用时候我们怎么去传这个token过去呢,有人会用@Headers这个注解来实现。但是这样方法太多笨重。我们可以使用RequestInterceptor 来实现。附上代码 import feign.RequestInterceptor; import feign.Request...
1.使用Feign 调用其他微服务,尤其是在多级调用的同时,需要将一些共同的参数传递至下一个服务,如:token。比较方便的做法是放在请求头,在Feign调用的同时自动将参数放到restTemplate。 2.具体做法是首先实现RequestInterceptor import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.stereotype.Component;
##问题背景 paas服务发生异常日志报警时,需要在paas服务把对应header信息打印出来,由于接口请求的是saas服务,所以saas调用paas时需要把hearer传递过去。 ##解决办法 新增Feign的配置类,实现RequestInterceptor接口的apply方法。 @Slf4j public class FeignConfig implements RequestInterceptor { @Override public void apply(RequestTemp
  用户登陆后,再次访问网页,将用户信息loginToken放在requestheader,首先经过网关,然后到达A服务,然后A服务调用B服务时如何把loginToken传递给B服务 1.修改hytrix配置,配置hytrix的strategy为SEMAPHORE。 Hystrix 提供两种执行隔离策略( ExecutionIsolationStrategy ) :SEMAPHORE、THREAD SEMAPHORE:信号量,命令在调用线程执行。 THREAD:线程池,命令在...
public class TestController { @GetMapping("") public R<?> testController(HttpServletRequest httpServletRequest){ String
Spring Cloud Feign传输Header,并保证多线程情况下也适用 微服务在生产,常遇到需要把 header 传递到下一子服务的情况(如服务A访问服务B的接口,需要传递header),网上大多数的方案是实现 RequestInterceptor 接口,在重写方法,把 header 填进 Feign 的请求。我们先按这种方式,简单实现代码如下: 1、继承RequestInterceptor 服务A新建类,继承 RequestInterceptor,把 header 设置到请求,注
问题:我们在调用feign的情况下,经常需要用到客户端所持有的header比如说auth-token,我们需要将这些header传递下去 思路:使用拦截器,在客户端拦截feign的请求,并把所需要的header传递下去 1.定义拦截器 @Configuration public class FeignInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate
@FeignClient(name = "your-service-name") public interface YourServiceClient { @RequestMapping(method = RequestMethod.POST, value = "/your-api") String yourApi(@RequestParam("img") String img); 其,@FeignClient注解用于声明一个Feign客户端,name属性指定了服务名。@RequestMapping注解用于声明请求映射,method属性指定了请求方法,value属性指定了请求路径。@RequestParam注解用于声明请求参数,img为参数名。 在调用时,可以使用以下代码: @Autowired private YourServiceClient yourServiceClient; String imgTag = "<img src='your-img-url' alt='your-img-alt'>"; String result = yourServiceClient.yourApi(imgTag); 其,your-img-url和your-img-alt为img标签的属性值。result为服务端返回的结果。