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

SpringBoot RestTemplate传含特殊字符查询参数时服务端接收异常问题

问题背景

我通过如下Java代码调用API接口:

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(myUrl);
builder.queryParam("sandwich","PB_&_J");

return restTemplate.exchange(builder.toUriString(),HttpMethod.GET,MyObject.class);

对应接口的服务端实现代码如下:

@GetMapping("myUrl")
MyObject myApiFunction( @RequestParam String sandwich){
    log(sandwich);
   //return something
}

服务端无法正确解析该请求,日志中打印的sandwich参数值为'%26',而非预期的'&'。但如果打印builder.toUriString()得到请求地址http://myurl?sandwich=PB_%26_J,通过Postman直接发起该地址的请求时,服务端可以正常消费请求、正确识别参数。

问题根因

问题出在RestTemplate的默认URL处理逻辑存在二次编码问题:

  • UriComponentsBuilder.toUriString()生成的URL已经完成了合规编码,参数里的&被转成%26,符合URL传输规范,这也是Postman直接调用该地址能正常被服务端解析的原因。
  • 当你把已经编码完成的URL字符串传入restTemplate.exchange()方法时,RestTemplate默认使用的DefaultUriBuilderFactory会对传入的字符串再次执行百分号编码:原本%26中的%会被二次编码为%25,最终服务端收到的参数实际为PB_%2526_J。服务端做一次URL解码后,拿到的值就是PB_%26_J,和你观察到的日志现象完全吻合。
修复方案

二选一即可解决问题:

  • 方案1:直接传入已编码完成的URI对象,跳过RestTemplate的字符串URL编码流程,这是最推荐的无侵入写法:
// 把toUriString()替换为toUri(),直接返回构建好的URI对象
return restTemplate.exchange(builder.toUri(), HttpMethod.GET, null, MyObject.class);
  • 方案2:修改RestTemplate的URI编码模式,关闭对传入URL的自动编码逻辑:
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
// 设置编码模式为NONE,直接使用传入的已编码URL,不做二次转义
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
restTemplate.setUriTemplateHandler(factory);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:57:19