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

RestTemplate.delete()调用中URL编码字符串重复编码的异常问题

解决RestTemplate删除请求中URL二次编码的问题

我之前也碰到过RestTemplate这个URL编码的坑,刚好能帮到你!

问题根源

你调试到的org.springframework.web.util.DefaultUriBuilderFactory.createURI()就是关键——RestTemplate默认使用这个类处理URI构建,它会自动对URI中的变量进行URL编码。这就导致了两种错误情况:

  • 如果你提前手动用URLEncoder.encode()编码路径,框架会把已经编码的%2F中的%再次编码成%25,最终变成%252F,接口无法识别;
  • 如果不提前编码,框架会把路径里的/当成路径分隔符,把test/test-cold-storage拆成两个路径段,不符合接口要求的单段编码格式。

正确解决方案

推荐按照Spring的设计思路来处理,以下几种方法都能解决问题:

1. 直接使用RestTemplate的变量替换(最推荐)

当你调用RestTemplate的方法时,把完整的项目路径作为一个单独的URI变量传入,框架会自动对这个变量里的特殊字符进行编码,不会二次处理:

String projectPath = "test/test-cold-storage";
restTemplate.delete("https://<removed>/api/v4/projects/{projectPath}", projectPath);

这样框架会自动把/编码成%2F,最终的URI就是正确的https://<removed>/api/v4/projects/test%2Ftest-cold-storage。

2. 使用UriComponentsBuilder构建URI

如果需要更精细地控制URI构建,可以用UriComponentsBuilder,它会正确处理路径段的编码:

String projectPath = "test/test-cold-storage";
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl("https://<removed>/api/v4/projects")
        .pathSegment(projectPath) // 这里会把整个projectPath作为一个路径段,自动编码其中的/
        .build()
        .encode();
URI uri = uriComponents.toUri();
restTemplate.delete(uri);

或者用变量占位符的方式:

UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl("https://<removed>/api/v4/projects/{projectPath}")
        .build()
        .expand("test/test-cold-storage")
        .encode();
URI uri = uriComponents.toUri();
restTemplate.delete(uri);

3. 关闭框架的自动编码(不推荐)

如果你一定要手动编码路径,可以通过配置DefaultUriBuilderFactory关闭自动编码,但这种方式需要确保所有路径变量都已经正确手动编码,容易出错:

DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory();
// 设置编码模式为NONE,框架不再自动编码
uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);

RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(uriBuilderFactory);

// 此时手动编码路径不会被二次处理
String encodedProjectPath = URLEncoder.encode("test/test-cold-storage", StandardCharsets.UTF_8.toString());
restTemplate.delete("https://<removed>/api/v4/projects/" + encodedProjectPath);

验证方法

你可以继续用自定义的CustomRequestInterceptor打印请求URI,确认最终的路径是test%2Ftest-cold-storage,而不是二次编码的test%252Ftest-cold-storage或者未编码的test/test-cold-storage。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 22:07:39