需求背景
使用 Fegin向 Spring Cloud Getaway 转发请求,在请求到达 Fegin 的入口程序时,对请求的参数进行解析、加密、判断等一系列别的操作时,使用 RequestInterceptor 即可处理参数,但其中有许多的坑。
使用场景
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
FeginInterceptor 拦截器简单实现,在 apply 方法里可以对请求进行处理。
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeginInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
// TODO
}
}
例如:
1、处理在转发时丢失的请求头。
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
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;
@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);
}
}
}
}
2、处理参数
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import feign.RequestInterceptor;
import feign.RequestTemplate;
@Configuration
public class FeignConfiguration implements RequestInterceptor{
@Override
public void apply(RequestTemplate template) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes != null) {
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
if (request != null) {
Enumeration<String> paramNames = request.getParameterNames();
if (paramNames != null) {
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
String values = request.getParameter(name);
// TODO
}
}
}
}
}
}
这个时候打印就会出现一个新的问题,在转发之前,Fegin 入口程序在调用 FeignClient 接口前在程序里处理的参数消失了。
其实不是消失了,而是获取的 HttpServletRequest 是原始请求的 request ,RequestTemplate 里存放的是 SpringCloud 从新封装的执行请求,里面含有在调用 FeignClient 接口前处理的所有信息与原始信息,属于两个不同的请求。
经过测试 RequestTemplate 内存放的东西难以获取。
抽空再补充后续内容
详见大佬博客:Spring Cloud Open Feign