项目使用springboot + springcloud分布式部署.之前由于业务原因,需要使用以下方法获取request,从request中获取部分Header数据.
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
今天给项目配置LCN分布式事务,配置完成后启动,发现暴露接口全部调用失败.
查找原因后发现RequestContextHolder获取为null.导致报错终止暴露接口的调用.
有两个问题需要解决:
1.使用LCN后如何获取请求的request.
2.上面代码获取resquest的代码部分属于公共代码,除了在Feign暴露接口拦截中使用,系统中还有其他多个地方使用
现在我需要一个公共的方法获取请求参数reqeust,请帮忙分析一下这个问题该如何解决?
我的springCloud中使用eureka注册服务,使用feign+hystrix自定义并发策略实现自定义请求头转发.代码如下:
public class FeignRequestInterceptor implements RequestInterceptor {
private Logger logger = LoggerFactory.getLogger(FeignClient.class);
@Override
public void apply(RequestTemplate requestTemplate) {
logger.debug("Feign Config init");
// 这里是根据系统配置的请求头从请求参数获取header,参考第一段代码
List<Header> headers = HeaderUtil.getSYSHeaders();
for (Header header : headers) {
requestTemplate.header(header.getKey(), header.getValue());
}
}
}
下面是hystrix自定义策略的配置,只粘贴了部分代码,下面代码中的RequestContextHolder.getRequestAttributes()也为空
@Component
public class FeignHystrixConcurrencyStrategyIntellif extends HystrixConcurrencyStrategy {
...
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
// 不开启LCN,这里正常获取
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
return new WrappedCallable<>(callable, requestAttributes);
}
static class WrappedCallable<T> implements Callable<T> {
private final Callable<T> target;
private final RequestAttributes requestAttributes;
public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) {
this.target = target;
this.requestAttributes = requestAttributes;
}
@Override
public T call() throws Exception {
try {
RequestContextHolder.setRequestAttributes(requestAttributes);
return target.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
}
在使用LCN分布式事务之前系统的配置没有问题,配置LCN并启用之后.hystrix自定义策略中的RequestContextHolder.getRequestAttributes()为空.
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
// 开启LCN后这里获取的值为null,即requestAttributes = null
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
return new WrappedCallable<>(callable, requestAttributes);
}