我尝试使用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字符串。是否有一种简单的方法可以阻止春天这样做?
此致
答案 0 :(得分:12)
没有简单的方法可以做到这一点。 URI模板变量通常用于路径元素或查询字符串参数。你正试图通过一个主机。理想情况下,您可以找到构建URI的更好解决方案。我建议Yuci's solution。
如果您仍想使用Spring实用程序和模板扩展,一种解决方法是使用UriTemplate
生成带有URI变量的URL,然后对其进行URL解码并将其传递给您的{ {1}}。
RestTemplate
答案 1 :(得分:8)
取决于您使用的是哪个版本的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)
答案 2 :(得分:4)
您可以使用带有java.net.URI的重载变体 public T getForObject(URI url,Class responseType)抛出RestClientException
UriComponents uriComponents =
UriComponentsBuilder.fromUriString("http://example.com/hotels/{hotel}/bookings/{booking}").build()
.expand("42", "21")
.encode();
URI uri = uriComponents.toUri();
答案 3 :(得分:1)
对于任何HttpMethod和ResponseType,标题,正文的完整示例可能如下所示:
String url = "http://google.com/{path}?param1={param1Value}¶m2={param2Value}";
Object body = null;
HttpEntity request = new HttpEntity(body, new HttpHeaders());
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("path", "search");
uriVariables.put("param1Value", "value1");
uriVariables.put("param2Value", "value2");
ResponseEntity<Void> responseEntity = restTemplate.exchange(url, HttpMethod.POST, request, Void.class, uriVariables)
//responseEntity.getBody()
实际上,它将使用相同的UriTemplate和expand方法
答案 4 :(得分:0)
好像我找到了最佳的本机方式(最新)解决方案:
dd($items->toArray())
array:3 [▼
0 => array:3 [▼
"id" => 10
"start_date" => "Jan 1997"
"end_date" => "Jan 2000"
]
1 => array:3 [▼
"id" => 9
"start_date" => "Jan 2000"
"end_date" => "Jan 2003"
]
2 => array:3 [▼
"id" => 6
"start_date" => "Jan 2007"
"end_date" => ""
]
]
来构造URI。请参见下面的(简化)示例:
array:3 [▼
0 => array:3 [▼
"id" => 6
"start_date" => "Jan 2007"
"end_date" => ""
]
1 => array:3 [▼
"id" => 9
"start_date" => "Jan 2000"
"end_date" => "Jan 2003"
]
2 => array:3 [▼
"id" => 10
"start_date" => "Jan 1997"
"end_date" => "Jan 2000"
]
]
这样,您就不会遇到双重编码问题。
基于Spring $items->sortByDesc('end_date')
客户端(包括SOQL查询)调试SalesForce REST客户端时发现解决方案。
答案 5 :(得分:0)
显然,有一种更好的方法可以通过调用UriComponentsBuilder类的build(true)来实现:
private void doLogout(String endpointUrl, String sessionId) {
String url = "http://" + endpointUrl +"?method=logout&session=" + + URLEncoder.encode(sessionId, "UTF-8");
URI uri = UriComponentsBuilder.fromUriString(url.toString()).build(true).toUri();
template.getForObject(uri, Object.class,
endpointUrl, sessionId);
}
此方法告诉URIComponentsBuilder在创建URI时不进行编码。