SpringCloudFeign请求拦截器说明
周所周知,feign在调用微服务系统中的某一服务时是无法携带前端请求后台时所带来的请求头信息的,例如token,这对于使用token验证的系统来说是很致命的;还有一种情况就是说当你使用Spring拦截器作为验证权限的方式时,需要区分请求是从系统外部发送来的还是系统内部发送来的,这个校验也可以使用请求头信息解决。下面先为大家展示一下Feign拦截器
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import feign.RequestInterceptor;
import feign.RequestTemplate;
/**
* Feign请求拦截器
* 为Feign访问其他服务时加上请求头
* @author a2417
*
*/
@Component
public class FeignRequestConfig implements RequestInterceptor{
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(attributes==null){
System.out.println("空针");
}
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
//获取前端传递的头信息
String values = request.getHeader("xtoken");
//添加头信息
requestTemplate.header("xtoken", values);
//添加自定义头信息
requestTemplate.header("fegin", "2190268123asd");
}
}
}
}
下面解释一下这里面的关键内容:
1. 这里有一个坑,可以看到我的代码中写入了一个判断空针的方法,这里需要说明的是,配置文件的加载优先级比较高,很可能会出现attributes为空的情况,解决办法可以是在启动类中加入以下代码,用以监听:
/**
* 监听器:监听HTTP请求事件
* 解决RequestContextHolder.getRequestAttributes()空指针问题
* @return
*/
@Bean
public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
2. 给该类加上一个@Component注解即可使全局Feign请求经过此拦截器,这里说一下为什么不用@Configuration注解的原因,因为@Configuration注解的优先级要高,这和我们上面说的问题有一定关连,@Configuration注解是已配置文件的编译方法启动的,里面的方法还需要加上@Bean注解,这样的优先级会使里面的attributes对象获取不到,如何真的想用@Configuration的话,可以将拦截器代码提出来做成一个对象,然后写一个@Configuration的类和一个带@bean的方法,里面返回提出来的对象即可!
3. 如果只有某个feign调用则可以这样设置(但配置类不能在扫描目录下):
@FeignClient(name = "organ",path = "/organ/OrganInfo",configuration = FeignSupportConfig.class)
这样就不能使用我上面说的方法了,只能把拦截器提出来封装一个对象!