首页 > 其他分享 >for循环外创建一个http请求对象,循环内赋值参数多次请求返回数据相同定位及解决(共用一个请求对象,不同请求参数,结果相同问题定位)

for循环外创建一个http请求对象,循环内赋值参数多次请求返回数据相同定位及解决(共用一个请求对象,不同请求参数,结果相同问题定位)

时间:2024-05-30 09:28:39浏览次数:24  
标签:info 定位 请求 form get jsonObject list 参数

一次项目线上问题定位 ,发现多次不同参数请求值相同 ,直接上代码

 List<String> list = new ArrayList<>();
        list.add("85657218,上海奉贤恒盛湖畔豪庭xxx号xxx");
        list.add("85657219,上海虹口虬江支路xxx弄xxx室");
if (CollectionUtil.isNotEmpty(list)) {
	HttpRequest get = HttpUtil.createGet("https://restapi.amap.com/v3/geocode/geo");
    list.forEach(address -> {
        String[] idAndaddress = address.split(",");
        get.form("address", idAndaddress[1]);
        get.form("key", "key");
        get.form("s", "rsv3");
        HttpResponse execute = get.execute();
        JSONObject jsonObject = JSONUtil.parseObj(execute.body());
        if ("OK".equals(jsonObject.getStr("info")) && "1".equals(jsonObject.getStr("status"))) {
            String locatioin = (String) jsonObject.getByPath("geocodes[0].location");
            String[] lngAndlat = locatioin.split(",");
            log.info("更新地址 :{}  ,  {} , {}", Convert.toInt(idAndaddress[0]), lngAndlat[0], lngAndlat[1]);
        } else {
            log.info("需求坐标补偿调用高德异常:{}", jsonObject.getStr("info"));
        }
    });
}

在这段代码中,list有两条不同地址的数据,需要依次请求高德拿到地址对应的经纬度,然而通过log.info打印发现两次不同的地址拿到的经纬度都是第一个地址的经纬度

于是开启debug之路,依次进入对应方法

get.execute()  →  doExecute()  → urlWithParamIfGet()

	private HttpResponse doExecute(boolean isAsync, HttpInterceptor.Chain interceptors) {
		if (null != interceptors) {
			for (HttpInterceptor interceptor : interceptors) {
				interceptor.process(this);
			}
		}

		// 初始化URL
		urlWithParamIfGet();
		// 初始化 connection
		initConnection();
		// 发送请求
		send();

		// 手动实现重定向
		HttpResponse httpResponse = sendRedirectIfPossible(isAsync);

		// 获取响应
		if (null == httpResponse) {
			httpResponse = new HttpResponse(this.httpConnection, this.charset, isAsync, isIgnoreResponseBody());
		}

		return httpResponse;
	}


	private void urlWithParamIfGet() {
		if (Method.GET.equals(method) && false == this.isRest) {
			// 优先使用body形式的参数,不存在使用form
			if (ArrayUtil.isNotEmpty(this.bodyBytes)) {
				this.url.getQuery().parse(StrUtil.str(this.bodyBytes, this.charset), this.charset);
			} else {
				this.url.getQuery().addAll(this.form);
			}
		}
	}

在urlWithParamIfGet方法初始化URL时会给表单的参数添加到路径的query中,可以看到表单参数的时候是给当前的表单参数叠加到当前请求对象的url的query中

第一次请求的参数
在这里插入图片描述
第二次请求的参数,长度是6 ,因为是公用一个request请求对象,所以给第二次请求的参数追加进第一次请求的地址里了在这里插入图片描述
这里可以看到第二次请求参数处理完发现 请求地址的query的长度是6,第二次的参数跟在第一次参数的后面,而不会清除旧的数据。这样会导致请求 URL 中的表单数据不断叠加,从而使每次请求发送的实际表单数据都是相同的,这也就导致了相同的请求结果
![在这里插入图片描述](/i/ll/?i=direct/6b14902d49754745869ee06d5501347b.png在这里插入图片描述
如何解决这个不同参数请求结果相同呢,给请求对象从循环外面拿到里面即可,每次都会创建一个新的url的query添加form参数

调整后代码:

List<String> list = new ArrayList<>();
        list.add("85657218,上海奉贤恒盛湖畔豪庭xxx号xxx");
        list.add("85657219,上海虹口虬江支路xxx弄xxx室");
if (CollectionUtil.isNotEmpty(list)) {
    list.forEach(address -> {
    	HttpRequest get = HttpUtil.createGet("https://restapi.amap.com/v3/geocode/geo");
        String[] idAndaddress = address.split(",");
        get.form("address", idAndaddress[1]);
        get.form("key", "key");
        get.form("s", "rsv3");
        HttpResponse execute = get.execute();
        JSONObject jsonObject = JSONUtil.parseObj(execute.body());
        if ("OK".equals(jsonObject.getStr("info")) && "1".equals(jsonObject.getStr("status"))) {
            String locatioin = (String) jsonObject.getByPath("geocodes[0].location");
            String[] lngAndlat = locatioin.split(",");
            log.info("更新地址 :{}  ,  {} , {}", Convert.toInt(idAndaddress[0]), lngAndlat[0], lngAndlat[1]);
        } else {
            log.info("需求坐标补偿调用高德异常:{}", jsonObject.getStr("info"));
        }
    });
}

标签:info,定位,请求,form,get,jsonObject,list,参数
From: https://blog.csdn.net/qq_41973632/article/details/139298828

相关文章

  • SpringBoot之ThreadLocal保存请求用户信息
    一、ThreadLocal概述 线程局部变量,创建一个线程变量后,针对这个变量可以让每个线程拥有自己的变量副本,每个线程是访问的自己的副本,与其他线程的相互独立。二、具体代码demo实现(1)创建user实例对象@DatapublicclassUserDTO{privateLonguserId;privateStringU......
  • 成为MySQL DBA后,再看ORACLE数据库(三、参数管理)
    一、参数文件在ORACLE11g及以后的版本中,ORACLE使用spfile作为数据库的参数文件,这是一个二进制文件,不能通过手工修改。SPFILE的引入使得对于参数的修改都可以在命令行完成,不需要手工修改,这也是为了减少了人为错误的发生。而在MySQL中,需要去手工维护my.cnf参数文件,主要原因是在MyS......
  • SAP:观察I_CALLBACK_USER_COMMAND 参数(按钮点击事件)
    1、从函数级SLVC_FULLSCREEN里复制 一个在”GUI状态“ 下的“STANDARD_FULLSCREEN”标准全屏幕到 程序Z16_04里。 标准工具添加 定义按钮(关闭、保存)主程序代码:*&---------------------------------------------------------------------**&ReportZ16_04*&利用......
  • filebeat配置参数add_kubernetes_metadata
    在Kubernetes集群中,我们可以使用Filebeat来从容器中收集日志,并为每个日志事件添加Kubernetes相关的元数据信息,例如Pod名称、命名空间、标签等。这样我们就可以更好地分析和理解日志数据。filebeat.inputs:-type:containerpaths:-/var/log/containers/*.log......
  • Dockerfile - 参数与详解
    只有FROM时必须的#在当前路径下构建test镜像,执行Dockerfile文件dockerbuild-ttest.1.FROM制定基于那个镜像进行构建FROMalpine:latest2.WORKDIR指定工作目录,执行shell脚本的工作目录WORKDIR/app3.COPYADD复制文件,将宿主机文件拷贝到镜像中ADD可以是网络资......
  • anova 的替代非参数方法
    Kruskal-Wallis测试是一种非参数方法,用于比较三个或更多个独立样本的中位数是否存在显著差异。在R语言中,你可以使用kruskal.test()函数来执行Kruskal-Wallis测试。以下是使用kruskal.test()函数的基本步骤:准备数据:确保你的数据是向量或因子形式,并且每个向量代表一个组。......
  • Tomcat源码解析(七):底层如何获取请求url、请求头、json数据?
    Tomcat源码系列文章Tomcat源码解析(一):Tomcat整体架构Tomcat源码解析(二):Bootstrap和CatalinaTomcat源码解析(三):LifeCycle生命周期管理Tomcat源码解析(四):StandardServer和StandardServiceTomcat源码解析(五):StandardEngine、StandardHost、StandardContext、Standard......
  • 梯度提升机器LightGBM集成学习回归、分类、参数调优可视化实例|附数据代码
    全文链接:https://tecdat.cn/?p=36275原文出处:拓端数据部落公众号LightGradientBoostedMachine(简称LightGBM)是一个开源库,它为梯度提升算法提供了高效且有效的实现。LightGBM通过添加一种自动特征选择的方式,并专注于提升具有较大梯度的样本,来扩展梯度提升算法。这可以显著加速......
  • 【数据驱动】【航空航天结构的高效损伤检测技术】一种数据驱动的结构健康监测(SHM)方法,
     ......
  • 《最新出炉》系列入门篇-Python+Playwright自动化测试-49-Route类拦截修改请求-下篇
    1.简介 在日常工作和学习中,自动化测试的时候:在加载页面时,可能页面出现很多不是很重要或者不是我们所关注的,这个时候我们就可以选择不加载这些内容,以提高页面加载速度,节省资源。例如:可能页面上图片比较多,而我们又不关心图片内容。那么,在加载页面时,可以选择不加载图片,以提高页面加......