使用Feign,模块之间调用传递参数HttpServletRequest request拿不到值问题

问题描述:

       spring boot 项目,多模块之间使用Feign调用,请求方的request对象在传递的过程中丢失,服务方request对象中没有相应值。

初始状态:

feign接口

@PostMapping("/xxxx")
       @ApiOperation(value = "xxxx", notes = xxxx")
       RestResult<JSONObject> testFeign() throws Exception;

实现:

@PostMapping("/xxxx")
       @ApiOperation(value = "xxxx", notes = xxxx")
       @Transactional(rollbackFor = Exception.class)
       public RestResult<JSONObject> testFeign(@Autowired HttpServletRequest request) throws Exception{
       }

调用:

feignClient.testFeign();

结果:

request中没有请求头中没有相应数据。

解决过程:

尝试修改参数注解,在feign接口中增加参数。依然拿不到。

解决方案:

修改feign配置

public class NativeFeignConfig {
    @Bean
    public RequestInterceptor getRequestInterceptor() {
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate requestTemplate) {
                ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
                HttpServletRequest req = servletRequestAttributes.getRequest();
                Map<String, Collection<String>> headerMap = new HashMap();
                //获取你需要传递的头信息
                String userId = req.getHeader(SessionConst.KEY_USER_ID);
                String userName = req.getHeader(SessionConst.KEY_USER_NAME);
                String token = req.getHeader(SessionConst.KEY_TOKEN);
                String systemRole = req.getHeader(SessionConst.KEY_USER_SYSTEMROLE_ID);
                headerMap.put(SessionConst.KEY_USER_ID, Arrays.asList(userId));
                headerMap.put(SessionConst.KEY_USER_NAME, Arrays.asList(userName));
                headerMap.put(SessionConst.KEY_TOKEN, Arrays.asList(token));
                headerMap.put(SessionConst.KEY_USER_SYSTEMROLE_ID, Arrays.asList(systemRole));
                //feign请求时,便可携带上该信息
                requestTemplate.headers(headerMap);
            }
        };
    }
}
注:创建一个自定义的hystrix 线程策略, 将servletRequestAttributes传入新线程中,并赋给RequestContextHolder:

public class MyHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
    @Override
    public <T> Callable<T> wrapCallable(Callable<T> callable){
        ServletRequestAttributes servletRequestAttributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return new Callable<T>() {
            @Override
            public T call() throws Exception {
                try {
                    if (null != servletRequestAttributes) {
                        RequestContextHolder.setRequestAttributes(servletRequestAttributes);
                    }
                    return callable.call();
                }finally {
                    RequestContextHolder.resetRequestAttributes();
                }
            }
        };
    }
}
@Configuration
public class HystrixConfig {
    @PostConstruct
    public void init(){
        HystrixPlugins.getInstance().registerConcurrencyStrategy(
                new MyHystrixConcurrencyStrategy()
        );
    }
}

在feign接口类中的注解上增加 :configuration= NativeFeignConfig.class

@FeignClient(value = "xxxx",configuration= NativeFeignConfig.class)

问题原因:

开启hystrix后,feign请求,会运行在hystrix管理的另一线程下。也就是说从请求方模块发送到服务方的请求参数可以正常传递,但是HttpServletRequest request对象并没有正常传递,从一个线程到另一个线程中时,request并没有跟随一起。需要手工组装request请求中的值。

 

 

 

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值