子线程中远程调用获取servletRequestAttributes为null

背景描述:

邮件发送功能,通过异步线程去执行邮件发送,发送过程中需要通过远程调用人员服务来获取收件人账号对应的邮件地址,远程调用会有个拦截器去根据请求的reques传递token信息,这时候会发现从上下文获取RequestAttributes为null.

@Component
public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        HttpServletRequest request = getServletRequest();
        if (null == request){
            return;
        }
        template.header("token", getServletRequest().getHeader("token"));
        template.header("systemId", getServletRequest().getHeader("systemId"));
    }
    private HttpServletRequest getServletRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        return ((ServletRequestAttributes) requestAttributes).getRequest();
    }
}

原因分析:

RequestContextHolder获取request,是基于ThreadLocal存储的信息,ThreadLocal类似于map一样存储key,value来存储requestAttributes信息,只不过它的key是当前运行线程。Springboot默认使用ThreadLocal把request设置到请求线程中,这样如果在请求方法里面另起一个子线程后再通过getRequestAttributes方法获取,是获取不到的。

解决方法:

所以要能让子线程能够获取到requestAttributes,可以使用InherbritableThreadlocal,可以通过

RequestContextHolder.setRequestAttributes(@Nullable RequestAttributes attributes, boolean inheritable)

来设置子线程共享attributes。
在子线程执行前执行:
异步调用,设置子线程共享

ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
RequestContextHolder.setRequestAttributes(servletRequestAttributes,true);

设置子线程共享

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值