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

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

 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 中的表单数据不断叠加,从而使每次请求发送的实际表单数据都是相同的,这也就导致了相同的请求结果
在这里插入图片描述
如何解决这个不同参数请求结果相同呢,给请求对象从循环外面拿到里面即可,每次都会创建一个新的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"));
        }
    });
}
  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

oNuoyi

你的鼓励将是我创作的做大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值