首页 > 其他分享 >异步线程处理request,导致参数获取为null

异步线程处理request,导致参数获取为null

时间:2024-02-23 15:58:17浏览次数:21  
标签:String age request getParameter age1 参数 线程 null

原文链接:千万不要把 Request 传递到异步线程里面!有坑!

一、post接口

接口参数:

 后端代码:

@PostMapping("/postTest")
public String postTest(HttpServletRequest request, HttpServletResponse response) {
    // AsyncContext asyncContext = request.startAsync(request, response);
    String age1 = request.getParameter("age");
    String name1 = request.getParameter("name");
    System.out.println("age1=" + age1 + ",name1=" + name1);
    new Thread(new Runnable() {
        @Override
        public void run() {
            String age2 = request.getParameter("age");
            String name2 = request.getParameter("name");
            System.out.println("age2=" + age2 + ",name2=" + name2);
            //模拟业务请求
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            age2 = request.getParameter("age");
            name2 = request.getParameter("name");
            System.out.println("age2=" + age2 + ",name2=" + name2);
            // asyncContext.complete();
        }
    }).start();
    return "post success";
}

执行结果:

注:多次请求,打印结果不变

 原因:

因为request 在 Tomcat 中是循环使用的,第一次和第二次获取参数时,request还没有被回收,sleep设置为10秒,第三次获取参数前,request已经被回收。

二、get接口

接口参数:

http://127.0.0.1:18086/finger-print/asyncRequestController/getTest?age=18

后端代码:

@GetMapping("/getTest")
public String getTest(HttpServletRequest request, HttpServletResponse response) {
    // AsyncContext asyncContext = request.startAsync(request, response);
    String age = request.getParameter("age");
    System.out.println("age=" + age);
    new Thread(() -> {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        String age1 = request.getParameter("age");
        System.out.println("age1=" + age1);
        // asyncContext.complete();
    }).start();
    return "success";
}

执行结果:

 注:两次请求结果不一致,第二次请求两次获取参数都为空

原因:

第一次请求,获取参数为空原因和post请求一样,第二次请求获取参数都为空的原因,与获取参数的原理有关,详细建议打开原文链接学习,这里只简单说明。

请求第一次获取参数时,会把所有入参解析到一个map中,并给出一个标识(didQueryParameters = true),表明参数已解析,后面获取参数都到map中获取,所以第一次打印age正常。

而第一次打印age1时,是在 sleep 2秒后,这时request已被回收利用,且 didQueryParameters 也被赋值为 false,map也被清空,所以获取为null,并且第一次打印age1,会导致 didQueryParameters 又被赋值为 true,但是异步线程的调用已经超出了request的生命周期,不会再被回收,所以 didQueryParameters 不会再改为 false。

因此第二次打印age时,不会重新进行解析参数到map中的操作,打印结果依然为null。

第二次打印age1,步骤同第一次打印age1。

 

标签:String,age,request,getParameter,age1,参数,线程,null
From: https://www.cnblogs.com/YeHuan/p/18029739

相关文章

  • C++多线程 第九章 高级线程管理
    第九章高级线程管理注意:本章内容由于教材本身问题,例子存在较大问题.请自行在理解基础上重新设计.在大多数系统上面,为每个可以与其他任务并行执行的任务分配一个单独的线程是不切实际的.但线程池允许尽量充分利用硬件提供的并发性.在线程池帮助下,可以被并发执行的任务......
  • 多线程系列(七) -ThreadLocal 用法及内存泄露分析
    一、简介在Javaweb项目中,想必很多的同学对ThreadLocal这个类并不陌生,它最常用的应用场景就是用来做对象的跨层传递,避免多次传递,打破层次之间的约束。比如下面这个HttpServletRequest参数传递的简单例子!publicclassRequestLocal{/***线程本地变量*/......
  • 一种用于多线程中间状态同步的屏障机制
    一种用于多线程中间状态同步的屏障机制为了解决在多线程环境中,需要一个内置的计数屏障对于多个线程中的某一个部分进行检查,确保所有线程均到达该点后才能继续执行。该屏障常被用于多线程流水线中的中间检查,适用于阶段分割,是一种有效的同步机制。此处构建了一个barrier类,其中arr......
  • 多线程相关
    一、多线程与锁0、用户空间和内核空间1、什么是进程:进程是资源分配的基本单位(形象理解为程序进入内存运行的内容)2、什么是线程:程序执行的基本单位3、CAS的低层实现是汇编通过lockcmpxchg指令实现CAS的原子性4、对象在内存中的存储布局(刚new出来的时候)/(对象头和类型指针......
  • 多线程系列(六) -等待和通知模型详解
    一、简介在之前的线程系列文章中,我们介绍了synchronized和volatile关键字,使用它能解决线程同步的问题,但是它们无法解决线程之间协调和通信的问题。举个简单的例子,比如线程A负责将int型变量i值累加操作到10000,然后通知线程B负责把结果打印出来。这个怎么实现呢?其中一个......
  • C# 采用HttpWebRequest 、WebClient和HttpClient下载https的文件异常问题
    今天有个客户反应,程序下载文件失败,无法正常使用。远程客户电脑后,查看错误日志,都是提示https:****************************.dll等一系列文件的下载错误提示提示基础连接已经关闭:发送时发生错误。在网上找了很多方案都没有能解决,大多都是https链接时增加指定协议,很遗憾未能解......
  • requests基础
    笔记requests模块-urllib模块-requests模块request模块:python中原生的一款基于网络请求的模块,功能非常强大,简单便捷,效率极高。作用:模拟浏览器发请求。如何使用:(requests模块的编码流程)-指定url-发起请求-获取响应数据-持久化存储环境......
  • [转帖]nginx利用request_body记录POST body(location中用proxy_pass)
    https://www.cnblogs.com/freedom-try/p/14699538.html1.完整过程1.1在nginx.conf中http里面添加配置如下:http{ ... log_formatpostdataescape=json'$remote_addr-$remote_user[$time_local]"$request" '$status$bod......
  • npm 报错 npm ERR! request to https://registry.npm.taobao.org/three failed, reaso
    1.问题描述npm使用淘宝镜像安装报错npmERR!codeCERT_HAS_EXPIREDnpmERR!errnoCERT_HAS_EXPIREDnpmERR!requesttohttps://registry.npm.taobao.org/xxxfailed,reason:certificatehasexpired2.错误原因错误提示已经告诉原因是淘宝镜像过期了!其实,早在2021......
  • python实战:用requests+json抓取接口
    一,安装requests1,用pip安装(venv)liuhongdi@192news%pip3installrequests2,查看所安装库的版本:(venv)liuhongdi@192news%pip3showrequestsName:requestsVersion:2.31.0Summary:PythonHTTPforHumans.Home-page:https://requests.readthedocs.ioAu......