首先,feign想要将请求头向下游传递需要重写feign包下的RequestInterceptor(feigin的拦截器),拦截feign请求进行处理。代码
@Configuration public class FeignRequestConfig implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { //获取当前线程的request ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); Enumeration<String> headers = request.getHeaderNames(); if(headers == null){ return; } //将heads向下传递 while (headers.hasMoreElements()){ String name = headers.nextElement(); String value = request.getHeader(name); requestTemplate.header(name,value); } } }
然而在开发过程中发现,netty接收的请求没有ServletRequestAttributes 这个servlet上下文。
但是,我可以将netty请求中的参数拿到,自己建一个servlet上下文!
上代码:
首先,建一个HttpServletRequest实现类
public class HttpServletHeaderEntity implements HttpServletRequest { private final ContainerRequestContext containerRequestContext; public HttpServletHeaderEntity(ContainerRequestContext containerRequestContext){ this.containerRequestContext = containerRequestContext; } @Override public Enumeration<String> getHeaderNames() { return Collections.enumeration(containerRequestContext.getHeaders().keySet()); } @Override public String getHeader(String s) { return containerRequestContext.getHeaderString(s); }
}
这里我只要Header信息,所以只实现两个对header操作的方法,其他方法都是return null就不贴过来了。
第二部,过滤netty请求,拿到nety请求信息,将请求头存到前面新建的HttpServletHeaderEntity ,放入servlet上下文中。
@Service @Provider public class RestfulGloablInfoFilterEndpoint implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext containerRequestContext) throws IOException { //将netty的请求头放入httpservlet上下文中,后续调用feign会从httpservlet上下文拿取传递。 HttpServletRequest httpServletRequest = new HttpServletHeaderEntity(containerRequestContext); ServletRequestAttributes attributes = new ServletRequestAttributes(httpServletRequest); RequestContextHolder.setRequestAttributes(attributes,true); } }