Openfeign动态设置Headers
在使用OpenFeign进行HTTP调用时,可以通过自定义Feign拦截器来动态设置请求头,并在请求头中加入签名参数。实现这一功能的步骤如下:
1. 引入Feign依赖
确保你的项目中已经引入了Feign的依赖。如果使用的是Spring Boot,可以在pom.xml
中添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 创建签名生成工具类
创建一个工具类,用于生成签名参数。通常,签名生成会基于请求的某些参数和一个预共享的密钥。
import org.springframework.util.DigestUtils;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;
public class SignatureUtil {
private static final String SECRET_KEY = "your-secret-key";
public static String generateSignature(Map<String, String> params) {
String data = params.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining("&"));
data += SECRET_KEY;
return DigestUtils.md5DigestAsHex(data.getBytes(StandardCharsets.UTF_8));
}
}
3. 创建自定义Feign拦截器
创建一个实现RequestInterceptor
接口的拦截器类,该类将负责在请求发送之前添加或修改请求头,并添加签名参数。
注意:这个类是放在客户端实现的。
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class CustomFeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
// 获取所有请求参数(包括URL和Body中的参数)
Map<String, String> params = new HashMap<>();
// URL中的参数
if (template.queries() != null) {
template.queries().forEach((key, values) -> {
if (values != null && !values.isEmpty()) {
params.put(key, values.iterator().next());
}
});
}
// Body中的参数(假设是表单提交)
if (template.body() != null) {
String body = new String(template.body());
for (String param : body.split("&")) {
String[] keyValue = param.split("=");
if (keyValue.length == 2) {
params.put(keyValue[0], keyValue[1]);
}
}
}
// 动态设置请求头,例如添加一个Token
template.header("Authorization", "Bearer " + getToken());
// 生成签名并添加到请求头
String signature = SignatureUtil.generateSignature(params);
template.header("Signature", signature);
}
private String getToken() {
// 获取Token的逻辑,例如从上下文中获取
return "your-dynamic-token";
}
}
4. 配置Feign客户端
在Spring Boot应用中,你需要启用Feign客户端。可以在主应用类上添加@EnableFeignClients
注解,并指定Feign客户端的包路径。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients(basePackages = "com.example.feignclients")
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}
5. 定义Feign客户端接口
定义你的Feign客户端接口,并确保其可以通过Spring的自动装配注入。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(name = "example-client", url = "https://api.example.com")
@RequestMapping("/api")
public interface ExampleClient {
@GetMapping("/data")
String getData();
}
6. 使用Feign客户端
在你的服务中,注入并使用Feign客户端。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ExampleService {
private final ExampleClient exampleClient;
@Autowired
public ExampleService(ExampleClient exampleClient) {
this.exampleClient = exampleClient;
}
public String fetchData() {
return exampleClient.getData();
}
}
通过以上步骤,你可以实现OpenFeign调用时动态设置请求头,并在请求头中加入签名参数的功能。这样,当通过ExampleClient
进行调用时,自定义的CustomFeignInterceptor
会拦截请求,动态设置请求头,并添加签名参数。