在设置feign请求的请求头透传(Header Propagation)时获取不到当前服务请求头的信息
问题:希望在每次feign请求的时候在请求头中设置请求本服务的请求头信息,也就是将请求头信息带到feign请求中,也就是请求头透传(Header Propagation),但是发现在配置中获取不到请求的信息,代码:
package com.winkeytech.config;import com.alibaba.nacos.common.utils.StringUtils;
import com.winkeytech.properties.FeignProperties;
import feign.RequestInterceptor;
import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;@Data
@Configuration
public class FeignHeaderConfig {private final FeignProperties feignProperties;@Beanpublic RequestInterceptor headerRequestInterceptor() {return requestTemplate -> {// 1. 先调用父类(Blade 默认逻辑,传递认证信息)// 如果你不继承 BladeFeignRequestInterceptor,可以跳过// super.apply(requestTemplate);// 2. 获取当前请求的 HttpServletRequestServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes == null) {// 非 Web 请求上下文(如定时任务),跳过透传return;}HttpServletRequest request = attributes.getRequest();// 3. 定义要透传的 Header 白名单(安全!不要透传所有 Header)Set<String> headersToPass = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("Tenant-Id","Authorization","X-Request-Id","X-User-Id","X-User-Name")));for (String headerName : headersToPass) {String value = request.getHeader(headerName);if (StringUtils.isNotBlank(value)) {requestTemplate.header(headerName, value);}}};}}
获取到的attributes变量为null,获取不到请求头中的信息
原因:因为使用Hystrix
解决:需要添加额外的配置类(如果是异步调用也要)
package com.winkeytech.config;import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;import java.util.concurrent.Callable;@Configuration
public class HystrixConfig {@Beanpublic HystrixConcurrencyStrategy hystrixConcurrencyStrategy() {return new HystrixConcurrencyStrategy() {@Overridepublic <T> Callable<T> wrapCallable(Callable<T> callable) {// 传播RequestContext到Hystrix线程RequestAttributes context = RequestContextHolder.currentRequestAttributes();return () -> {try {RequestContextHolder.setRequestAttributes(context);return callable.call();} finally {RequestContextHolder.resetRequestAttributes();}};}};}
}