@Headers 注解在 Netflix Feign 中用于定义请求头(HTTP Headers)信息。它允许你在 Feign 客户端接口方法上指定一系列固定的请求头,这些请求头会在每次调用该方法发送请求时自动添加到 HTTP 请求中。这对于需要传递认证信息、内容类型说明或者其他固定的请求头信息的场景非常有用。
(1)如果将 @Headers 注解放在接口上,则接口下面所有的方法将会共享该 @Headers,如下:
@Headers("Content-Type: application/xml")
interface SoapApi {
// ...
@RequestLine("GET /simple/get1")
String get1();
@RequestLine("GET /simple/get2")
String get2();
// ...
}上述示例中,get1 和 get2 发起的请求上均会自动添加“Content-Type: application/xml”请求头。
(2)在方法上添加 @Headers 注解,则仅会在该方法发起的请求中添加请求头。下面将在请求中添加“Cache-Control”请求头。如下:
@RequestLine("GET /")
@Headers("Cache-Control: max-age=640000")
String index();如果传递多个请求头,示例如下:
@RequestLine("POST /")
@Headers({
"X-Foo: Bar",
"X-Ping: {token}"
})
void post(@Param("token") String token);注意:上述示例中,{token} 变量将被解析为 token 的实际值。
如果你想在请求头部中直接使用花括号("{}"),需要对其进行 URL 编码。
如果请求头中具有相同名称的请求头,请求头不会相互覆盖,所有请求头都将包含在请求中。
Feign 与 JAXRS 的关系,以下两种形式是相同的:
Feign:
@RequestLine("POST /")
@Headers({
"X-Ping: {token}"
})
void post(@Named("token") String token);JAX-RS:
@POST
@Path("/")
void post(@HeaderParam("X-Ping") String token);假设你有一个服务需要进行纯文本数据交互并且需要传递认证信息。可以像下面这么做:
(1)服务代码:
@GetMapping("/header1")
public String header1(@RequestHeader("Custom-Header") String customHeader,
@RequestHeader("Authorization") String token,
@RequestHeader("Content-Type") String contentType) {
return "Custom-Header=" + customHeader +
"<br/>Authorization=" + token +
"<br/>Content-Type=" + contentType;
}(2)Feign 客户端接口定义:
@Headers("Custom-Header: SimpleFeign.java")
public interface SimpleFeign {
//...
@RequestLine("GET /simple/header1")
@Headers({
"Authorization: Bearer {token}",
"Content-Type: text/plain"
})
String header1(@Param("token") String token);
//...
}(3)调用 Feign 客户端:
@GetMapping("/")
public String index() {
return SimpleFeign.create().header1("hello world");
}输出结果如下:

上面示例中,@Headers 注解定义了两个请求头。一个是 Content-Type 请求头,指定了请求的数据格式为纯文本。另一个是 Authorization 请求头,用于传递认证令牌(这里假设是基于 Bearer 认证的方式),服务端可以根据这个令牌来验证请求的合法性。
注意:还在类上面添加了“Custom-Header”请求头。
下面是 Headers 源码:
package feign;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Headers {
// 定义 HTTP 请求头
String[] value();
}源码中,value 是属性名,它的返回值类型是 String 数组。这意味着当我们在使用 @Headers 注解时,可以通过给 value 属性赋值来定义一系列的 HTTP 请求头。