SpringCloud中分析讲解Feign组件添加请求头有哪些坑梳理

  • Post category:http

下面是针对Spring Cloud中Feign组件添加请求头的完整攻略:

第一步:添加依赖

在pom.xml文件中添加对feign-corefeign-okhttp的依赖,同时如果想要使用Spring Cloud中的相关功能,还需添加相应的Spring Cloud依赖,如下所示:

<!-- feign依赖 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-core</artifactId>
    <version>${feign.version}</version>
</dependency>
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
    <version>${feign.version}</version>
</dependency>

<!-- spring cloud依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>${spring-cloud.version}</version>
</dependency>

第二步:注解方式添加请求头

在使用Feign进行接口调用时,可以通过注解的方式来添加请求头信息,如下所示:

@Headers("X-Request-Id: {requestId}")
@GetMapping("/test")
String test(@PathVariable("requestId") String requestId);

上述示例代码中,通过@Headers注解来添加名为X-Request-Id的请求头信息,并通过占位符的方式将变量requestId的值动态设置到请求头中。

第三步:全局配置方式添加请求头

除了注解方式之外,还可以通过全局配置的方式来添加请求头信息,不需要再每个接口上加注解。实现这一功能,需要创建一个自定义的FeignRequestInterceptor拦截器,并注册到Spring容器中,如下所示:

@Component
public class MyFeignRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        // 添加自定义请求头信息
        template.header("X-Request-Id", UUID.randomUUID().toString());
    }
}

上述示例代码中,创建了一个自定义的FeignRequestInterceptor拦截器,其中在apply()方法中添加了名为X-Request-Id的请求头信息,并将其值设置为一个随机的UUID。

注意事项

注意1:Feign自带注解

在使用Feign时,需要注意自带的注解和Spring Cloud的注解有所不同,如下所示:

Feign注解 Spring Cloud注解
@RequestLine @RequestMapping
@Param @RequestParam
@Headers
@Body

注意2:请求头中的占位符

当使用@Headers注解来添加请求头信息时,需要注意请求头中占位符的使用方式,如下所示:

@Headers("X-Request-Id: {requestId}")
@GetMapping("/test")
String test(@PathVariable("requestId") String requestId);

上述示例代码中,通过占位符的方式将变量requestId的值动态设置到请求头中,需要注意占位符的使用方式必须是花括号{}包裹。

另外,对于某些特殊字符,也需要进行转义,如:和空格等,示例代码如下:

@Headers("X-My-Header: test\\:value")
@GetMapping("/test")
String test();

上述示例代码中,在X-My-Header请求头中添加了一个test:value的值,其中对:进行了转义。

示例代码

最后,附上完整的示例代码供参考:

@RestController
public class MyController {

    @Autowired
    private MyFeignClient myFeignClient;

    @GetMapping("/test")
    public String test() {
        return myFeignClient.test(UUID.randomUUID().toString());
    }
}

@FeignClient(name = "myFeignClient", url = "http://localhost:8080")
public interface MyFeignClient {

    @Headers("X-Request-Id: {requestId}")
    @GetMapping("/test")
    String test(@PathVariable("requestId") String requestId);
}

@Component
public class MyFeignRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        // 添加自定义请求头信息
        template.header("X-Request-Id", UUID.randomUUID().toString());
    }
}

上述示例代码中,创建了一个MyFeignClient接口来调用远程接口,使用了@Headers注解来添加(动态)请求头信息。

同时,还创建了一个MyFeignRequestInterceptor拦截器,将其注册到Spring容器中实现全局配置。最终,在MyController中注入MyFeignClient并调用其test()方法来演示使用Feign添加请求头的方式。