spring resttemplate url encoding

匿名 (未验证) 提交于 2019-12-03 03:03:02

问题:

I try to do a simple rest call with springs resttemplate:

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

Where the endpointUrl variable contains something like service.host.com/api/service.php

Unfortunately, my call results in a org.springframework.web.client.ResourceAccessException: I/O error: service.host.com%2Fapi%2Fservice.php

So spring seems to encode my endpointUrl string before during the creation of the url. Is there a simple way to prevent spring from doing this?

Regards

回答1:

There is no easy way to do this. URI variables are usually meant for one path element or a query string parameter. You're trying to pass multiple elements.

One workaround is to use UriTemplate to produce the URL with the URI variables as you have them, then URL-decode it and pass that to your 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); 


回答2:

Depends on which version of Spring you're using. If your version is too old, for example, version 3.0.6.RELEASE, you'll not have such facility as UriComponentsBuilder with your spring-web jar.

What you need is to prevent Spring RestTemplate from encoding the URL. What you could do is:

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); 

I tested it with Spring version 3.0.6.RELEASE, and it works.

In a word, instead of using restTemplate.getForObject(String url, Object.class), use restTemplate.getForObject(java.net.URI uri, Object.class)

See the rest-resttemplate-uri section of the Spring document



回答3:

You can use the overloaded variant that takes a java.net.URI instead public T getForObject(URI url, Class responseType) throws RestClientException

From Spring's own documentation

UriComponents uriComponents =     UriComponentsBuilder.fromUriString("http://example.com/hotels/{hotel}/bookings/{booking}").build()         .expand("42", "21")         .encode();  URI uri = uriComponents.toUri(); 


回答4:

Full example with headers, body, for any HttpMethod and ResponseType could look like:

String url = "http://google.com/{path}?param1={param1Value}&param2={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() 

Actually, it will use the same UriTemplate and expand method



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!