我尝试使用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错误:service.host.com%2Fapi%2Fservice.php
所以spring似乎在创建url之前编码了我的endpointUrl字符串.是否有一种简单的方法可以防止弹簧这样做?
问候
没有简单的方法可以做到这一点.URI变量通常用于一个路径元素或查询字符串参数.你试图传递多个元素.
一种解决方法是使用UriTemplate
生成带有URI变量的URL,然后对其进行URL解码并将其传递给您RestTemplate
.
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);
您可以使用采用java.net.URI的重载变量,而不是public T getForObject(URI url,Class responseType)抛出RestClientException
从Spring自己的文档中
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/hotels/{hotel}/bookings/{booking}").build() .expand("42", "21") .encode(); URI uri = uriComponents.toUri();
取决于您使用的是哪个版本的Spring.如果您的版本太旧,例如版本3.0.6.RELEASE,那么您将无法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部分