首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

RequestContextHolder.getRequestAttributes()在@Async之后获取null

RequestContextHolder.getRequestAttributes()在@Async之后获取null的原因是因为@Async注解会开启一个新的线程来执行被注解的方法,而RequestContextHolder.getRequestAttributes()方法是通过ThreadLocal来获取当前线程的请求属性,由于新线程没有继承父线程的ThreadLocal变量,所以在新线程中调用该方法会返回null。

解决这个问题的方法是使用CompletableFuture或者自定义的ThreadLocal来传递请求属性。具体步骤如下:

  1. 在异步方法中,将需要的请求属性保存到一个自定义的ThreadLocal变量中,例如:
代码语言:txt
复制
ThreadLocal<ServletRequestAttributes> requestAttributesHolder = new ThreadLocal<>();
requestAttributesHolder.set((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
  1. 在异步方法中,使用CompletableFuture来包装异步任务,并在异步任务中获取保存在ThreadLocal中的请求属性,例如:
代码语言:txt
复制
CompletableFuture.supplyAsync(() -> {
    // 在异步任务中获取请求属性
    ServletRequestAttributes requestAttributes = requestAttributesHolder.get();
    // 执行异步任务的逻辑
    // ...
    return result;
});

通过这种方式,可以在异步任务中获取到正确的请求属性。

需要注意的是,使用自定义的ThreadLocal需要在异步任务执行完毕后手动清除ThreadLocal中的值,以避免内存泄漏。可以在异步任务执行完毕后,添加清除ThreadLocal的代码,例如:

代码语言:txt
复制
CompletableFuture.supplyAsync(() -> {
    // 在异步任务中获取请求属性
    ServletRequestAttributes requestAttributes = requestAttributesHolder.get();
    // 执行异步任务的逻辑
    // ...
    return result;
}).whenComplete((result, throwable) -> {
    // 异步任务执行完毕后清除ThreadLocal
    requestAttributesHolder.remove();
});

这样就可以解决在@Async之后调用RequestContextHolder.getRequestAttributes()获取null的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

SpringBoot入门建站全系列(二十二)异步任务执行的几种方式

Spring提供的@Async注解。其实也是基于线程池。 注意Runnable和Callable异步任务中的应用,一个不带返回值,一个带返回值而已。 本文是Springboot环境中测试的。...web项目中测试会比较方便,我们利用RequestContextHolder获取ThreadLocal的Request对象来判断线程是否改变了 假设我们要执行的任务是这样的, 为了异步执行AsyncTaskService...中塞入一个值,后面用来获取判断是否是主线程。...四、线程池方式 首先我们Request中塞入一个值,后面用来获取判断是否是主线程。 然后将异步任务扔给线程池执行。 这里我们分别使用Runnable和Callable来测试下。...五、Spring的@Async注解方式 @Async注解的方法,不能和调用方法同一个类中,因为它是动态代理调用的。同一个类中动态代理个毛啊。。

89840
  • SpringBoot入门建站全系列(二十二)异步任务执行的几种方式

    Spring提供的@Async注解。其实也是基于线程池。 注意Runnable和Callable异步任务中的应用,一个不带返回值,一个带返回值而已。 本文是Springboot环境中测试的。...web项目中测试会比较方便,我们利用RequestContextHolder获取ThreadLocal的Request对象来判断线程是否改变了 假设我们要执行的任务是这样的, 为了异步执行AsyncTaskService...中塞入一个值,后面用来获取判断是否是主线程。...四、线程池方式 首先我们Request中塞入一个值,后面用来获取判断是否是主线程。 然后将异步任务扔给线程池执行。 这里我们分别使用Runnable和Callable来测试下。...五、Spring的@Async注解方式 @Async注解的方法,不能和调用方法同一个类中,因为它是动态代理调用的。同一个类中动态代理个毛啊。。

    1.2K30

    SpringBoot异步任务获取HttpServletRequest

    前言 使用框架日常开发中需要在controller中进行一些异步操作减少请求时间,但是发现在使用@Anysc注解后会出现Request对象无法获取的情况,本文就此情况给出完整的解决方案 原因分析 @...Anysc注解会开启一个新的线程,主线程的Request和子线程是不共享的,所以获取null 使用springboot的自定带的线程共享后,代码如下,Request不为null,但是偶发的其中body.../head/urlparam内容出现获取不到的情况,是因为异步任务未执行完毕的情况下,主线程已经返回,拷贝共享的Request对象数据被清空 ServletRequestAttributes servletRequestAttributes...Request清除结束不会影响到子线程的相应参数的获取,也适用于增加拦截器/过滤器后body参数无法重复获取的问题。...// chain.doFiler方法中传递新的request对象 if (requestWrapper == null) { chain.doFilter(request

    70260

    使用async await通过for循环图片onload加载成功后获取成功的图片地址

    需求:有一个图片列表,我想要在图片onload成功之后获取加载成功的图片列表,图片资源加载为异步,我们使用ES7的async await方式实现,多张图片,是用for循环。...注意:图片加载失败一定要加监听,await只有在有返回之后才会继续向下执行,无论成功与失败,否则第一张图加载失败,下面的await的都不会执行。...1557306553-NZiDWHaGKu.jpg", "http://img5.imgtn.bdimg.com/it/u=3025209343,1849399022&fm=26&gp=0.jpg"] async...}) } }catch(err){ console.log(err) } } getSuccessImageList() 以上图片链接从百度图片获取...参考链接: https://zhuanlan.zhihu.com/p/68117645 https://stackoverflow.com/questions/46399223/async-await-in-image-loading

    3.4K10

    NginxCDN加速之后获取用户真实IP做并发访问限制的方法

    开启CDN之后,我之前写的Shell防护脚本也就宣告无效了,因为不管是正常访问还是攻击访问,脚本拿到的IP都是CDN节点的,而我不可能把CDN的节点IP也给禁用了,那就都不能访问了(其实已经犯过错了,导致天津...---- 二、CDN之后 目前国内已经争相出现了百度云加速、加速乐、360网站卫士以及安全宝等免费CDN。让我们这些小网站也能免费享受以前高大上的CDN加速服务。...可以看到经过好多层代理之后, 用户的真实IP 第一个位置, 后面会跟一串中间代理服务器的IP地址,从这里取到用户真实的IP地址,针对这个 IP 地址做限制就可以了。...fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; } } 隔了几分钟之后的效果

    3.8K30

    CSE下RequestContextHolder.getRequestAttributes()为null

    Springmvc它有对request和response这些对象进行上下文存储; 可以通过下面代码获取到request和response RequestAttributes requestAttributes...= RequestContextHolder.getRequestAttributes(); HttpServletRequest request = ((ServletRequestAttributes...getRequest(); HttpServletResponse response = ((ServletRequestAttributes)requestAttributes).getResponse(); 但是RequestContextHolder.getRequestAttributes...();这个一直NULL ,我用的CSE框架,测试过SpringBoot,不用注册监听器能正常获取到,但CSE真的头疼,看了很多博客,说是要注入监听器 @Bean public RequestContextListener...所以我就在自定义的RequestContextListener里面设置: RequestContextHolder.setRequestAttributes(attributes,true); 最后还是null

    2.2K10

    项目知识盲区整理4

    项目知识盲区整理4 常用富文本编译器集合 常用图表插件 常用字体插件 验证码 element jwt 跨域--origin请求头 非Controller层通过RequestContextHolder.getRequestAttributes...configurationPropertiesBeans‘ defined in class path resource异常分析 RedisTemplate操作Redis Redis设置密码登录 使用Mybatis-Plus查询时某些字段为null...spring.redis.lettuce.pool.min-idle=0 #redis连接的密码 spring.redis.password=126433zdh ---- 使用Mybatis-Plus查询时某些字段为null...的情况,自动驼峰 我们使用mybatis plus 时, mybatis plus 可以帮我们自动封装我们的实体类用来查询添加,当我们遇见我们的实体类名与我们的表字段均为驼峰写法时: 例如实体类中有一个字段为...userName,而我们在数据库的字段名也是 userName 默认的驼峰式编码mybatis plus 则会默认把驼峰式编码写成 user_name, 这种下划线格式的字段 这时你会发现你的代码会出错

    49810
    领券