use*_*874 13 java spring resttemplate
我尝试使用spring resttemplate进行简单的休息调用:
private void doLogout(String endpointUrl, String sessionId) {
template.getForObject("http://{enpointUrl}?method=logout&session={sessionId}", Object.class,
endpointUrl, sessionId);
}
Run Code Online (Sandbox Code Playgroud)
endpointUrl变量包含service.host.com/api/service.php之类的内容
不幸的是,我的调用导致org.springframework.web.client.ResourceAccessException:I/O错误:service.host.com%2Fapi%2Fservice.php
所以spring似乎在创建url之前编码了我的endpointUrl字符串.是否有一种简单的方法可以防止弹簧这样做?
问候
Sot*_*lis 13
没有简单的方法可以做到这一点.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);
Run Code Online (Sandbox Code Playgroud)
Dmi*_*nov 11
看起来我找到了最好的本地方式(最新)解决方案:
RestTemplate.exchange()UriComponentsBuilder来构建URI。请参阅下面的(简化)示例:
String instanceUrl = "https://abc.my.salesforce.com"
HttpEntity<String> entity = new HttpEntity<>(headers);
UriComponents uriComponents =
UriComponentsBuilder.fromHttpUrl(instanceUrl)
.path("/services/data/v45.0/query/")
.queryParam("q", String.format(sqlSelect, id))
.build();
ResponseEntity<OpportunityLineItem> responseEntity =
restTemplate.exchange(
uriComponents.toUri(), HttpMethod.GET,
entity, OpportunityLineItem.class);
// Wrong! URI string will be double encoded
/*
ResponseEntity<OpportunityLineItem> responseEntity =
restTemplate.exchange(
uriComponents.toUriString(), HttpMethod.GET,
entity, OpportunityLineItem.class);
*/
Run Code Online (Sandbox Code Playgroud)
这样你就不会遇到双重编码的问题。
解决方案是在调试 SalesForce REST 客户端时找到的,基于 SpringRestTemplate客户端(包括 SOQL 查询)。
Yuc*_*uci 10
取决于您使用的是哪个版本的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);
Run Code Online (Sandbox Code Playgroud)
我用Spring版本3.0.6.RELEASE测试它,它的工作原理.
总之restTemplate.getForObject(String url, Object.class),使用而不是使用restTemplate.getForObject(java.net.URI uri, Object.class)
请参阅Spring文档的rest-resttemplate-uri部分
小智 5
您可以使用采用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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50333 次 |
| 最近记录: |