You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RestTemplate URL二次编码问题:原因及解决方法

问题:RestTemplate导致URL参数二次编码,API请求被拒

手动拼接的URL末尾为&timezone=Europe%2FBerlin,但通过RestTemplate发送请求时,该参数被修改为&timezone=Europe%252FBerlin(%被二次编码为%25),导致目标API拒绝请求。

原因分析

RestTemplate默认会对传入的URL字符串执行自动URL编码操作。你手动将时区参数中的/编码为%2F,相当于已经完成了一次编码;当RestTemplate处理这个预编码的URL时,会把其中的%字符当作普通字符再次编码,最终%2F就变成了%252F,造成二次编码,不符合API的参数格式要求。

修复方案

方案1:取消手动编码,让RestTemplate自动处理

直接使用原始的时区字符串Europe/Berlin,不再手动编码/,RestTemplate会自动将特殊字符编码为符合规范的格式。

修改业务代码中的getDates方法:

String getDates(String start, String end) {
    // 直接用Europe/Berlin,不再手动编码
    return String.format("&start_date=%s&end_date=%s", start, end) + "&timezone=Europe/Berlin";
}

此时RestTemplate会自动将/编码为%2F,最终参数为&timezone=Europe%2FBerlin,符合API要求。

方案2:直接构造URI对象,绕过自动编码

如果必须使用预编码的URL,可以直接通过URI.create()构造URI对象,RestTemplate会直接使用该URI,不再执行编码操作。

修改测试代码中的调用逻辑:

@Test
void test() {
    double lat = 52.52;
    double lon = 13.41;
    String start = "2023-04-01";
    String end = "2023-04-03";
    String urlStr = openMeteoService.getFullUrl(lat, lon, start, end);
    System.out.println(urlStr);
    RestTemplate restTemplate = new RestTemplate();
    // 直接构造URI对象,避免二次编码
    URI uri = URI.create(urlStr);
    OpenMeteoEntity forObject = restTemplate.getForObject(uri, OpenMeteoEntity.class);
    System.out.println(forObject);
}

方案3:自定义UriTemplateHandler(不推荐)

通过自定义UriTemplateHandler关闭自动编码,但这种方式可能导致其他参数无法正确编码,仅适用于特殊场景:

RestTemplate restTemplate = new RestTemplate();
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
restTemplate.setUriTemplateHandler(factory);

验证

修改后重新运行测试,RestTemplate发送的URL参数将保持正确的Europe%2FBerlin格式,API可以正常处理请求。

内容的提问来源于stack exchange,提问作者Pioter88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 08:02:58