弹簧 resttemplate url 编码

2022-09-01 20:03:40

我尝试用spring resttemplate做一个简单的休息调用:

private void doLogout(String endpointUrl, String sessionId) {
    template.getForObject("http://{enpointUrl}?method=logout&session={sessionId}", Object.class,
            endpointUrl, sessionId);
}

其中 endpointUrl 变量包含类似 service.host.com/api/service.php

不幸的是,我的调用导致 org.springframework.web.client.ResourceAccessException: I/O error: service.host.com%2Fapi%2Fservice.php

因此,spring似乎在创建url之前对我的端点Url字符串进行了编码。有没有一种简单的方法来防止春天这样做?

问候


答案 1

没有简单的方法来做到这一点。URI 模板变量通常用于路径元素或查询字符串参数。您正在尝试传递主机。理想情况下,您会找到更好的解决方案来构造 URI。我建议玉慈的解决方案

如果您仍然想使用Spring实用程序和模板扩展,一种解决方法是使用URI变量生成URL,然后对其进行URL解码并将其传递给您的.UriTemplateRestTemplate

String url = "http://{enpointUrl}?method=logout&session={sessionId}";
URI expanded = new UriTemplate(url).expand(endpointUrl, sessionId); // this is what RestTemplate uses 
url = URLDecoder.decode(expanded.toString(), "UTF-8"); // java.net class
template.getForObject(url, Object.class);

答案 2

取决于您使用的Spring版本。如果您的版本太旧,例如版本3.0.6.RELEASE,您将没有像spring-web jar那样的功能。UriComponentsBuilder

您需要的是防止Spring RestTemplate对URL进行编码。您可以做的是:

import java.net.URI;

StringBuilder builder = new StringBuilder("http://");
builder.append(endpointUrl);
builder.append("?method=logout&session=");
builder.append(sessionId);

URI uri = URI.create(builder.toString());
restTemplate.getForObject(uri, Object.class);

我用Spring版本3.0.6.RELEASE测试了它,它的工作原理。

一句话,与其使用 ,不如使用restTemplate.getForObject(String url, Object.class)restTemplate.getForObject(java.net.URI uri, Object.class)

请参阅 Spring 文档的 rest-resttemplate-uri 部分


推荐