前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java开发笔记之%被转码为%25导致url无法请求

Java开发笔记之%被转码为%25导致url无法请求

作者头像
Jetpropelledsnake21
发布2022-05-16 08:06:27
2.2K0
发布2022-05-16 08:06:27
举报
文章被收录于专栏:JetpropelledSnake

0x00 概述

在使用RestTemplate(import org.springframework.web.client.RestTemplate)进行开发时候发现,

拼装好的url请求在经过RestTemplate发送HTTP请求时候,url会被再次经行UrlEncode编码,导致已经拼装好的url内多出很多%25。

参考此RestTemplate经典问题:%被转码为%25导致url错误,殊途同归的解决方案。

由于请求路径内带有{}, 导致Spring认为这里是传参,还会引发日志报错:

代码语言:javascript
复制
Spring. Exception- Not enough variables available to expand xxxxxx

0x01 问题经过

由于业务和转码需要,需要在RestTemplate发送请求之前,,拼装好完整的URL请求路径,拼装代码如下:

代码语言:javascript
复制
String queryUrl =  serverURL+"?query="+ URLEncoder.encode(serverQL, StandardCharsets.UTF_8.toString());

以上会发现queryUrl是正常字符串+部分字符串进行了URLEncoder,样例如下:

代码语言:javascript
复制
// http://192.168.150.24:31190/api/v1/query?query=sum(irate(container_cpu_usage_seconds_total%7Bcontainer_name!%3D%27POD%27%7D%5B5m%5D))%20by%20(namespace%2C%20container_name)

在经过RestTemplate发送后,queryUrl变成了如下:

代码语言:javascript
复制
// http://192.168.150.24:31190/api/v1/query?query=sum(irate(container_cpu_usage_seconds_total%257Bcontainer_name!%253D%2527POD%2527%257D%255B5m%255D))%2520by%2520(namespace%252C%2520container_name)

仔细对比会发现%被转码为%25,使用站长工具urlencode, 使用UrlDecode解码两次,才能恢复到最初的queryUrl;

说明query字符串部分被进行了2次UrlDecode;

0x03 问题解决

在将queryUrl传入RestTemplate之前,将其封装为一个URL对象,避免了queryUrl被RestTemplate进行2次UrlDecode

代码语言:javascript
复制
String queryUrl =  serverURL+"?query="+ URLEncoder.encode(serverQL, StandardCharsets.UTF_8.toString());
URI uriObj = URI.create(queryUrl);
String http = null;
try {
        http = RestTemplateUtil.get(uriObj);
        log.info("【监控指标】查询结果:" + http);
} catch (Exception e) {
        log.error("【监控指标】获取异常,请求地址:{},请求指标:{},异常信息:{}", serverURL, serverQL, e);
}

 同时RestTemplate传参也是传入一个URL对象:

代码语言:javascript
复制
public static String get(URI url) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept", "application/json");
        headers.add("Content-Encoding", "UTF-8");
        headers.add("Content-Type", "application/json; charset=UTF-8");
        HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
        ResponseEntity<String> response = RestTemplateUtil.getInstance().exchange(url, HttpMethod.GET, requestEntity, String.class);
        String responseBody = response.getBody();
        return responseBody;
}

0x04 参考

Stackoverflow:Using RestTemplate in Spring. Exception- Not enough variables available to expand

Stackoverflow报错日志大宝库~~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 概述
  • 0x01 问题经过
  • 0x03 问题解决
  • 0x04 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档