Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring resttemplate url encoding

Tags:

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

like image 621
user1145874 Avatar asked Jan 02 '14 14:01

user1145874


People also ask

How do I encode a URL in spring boot?

encode method. Look at the below sample code. String url = "http://example.com/filter1/filter2/"; String value = "Art: Is It Value?"; String newValue = URLEncoder. encode(value, StandardCharsets.

Why RestTemplate is deprecated?

RestTemplate provides a synchronous way of consuming Rest services, which means it will block the thread until it receives a response. RestTemplate is deprecated since Spring 5 which means it's not really that future proof. First, we create a Spring Boot project with the spring-boot-starter-web dependency.

Is RestTemplate synchronous or asynchronous?

RestTemplate uses Java Servlet API and is therefore synchronous and blocking. Conversely, WebClient is asynchronous and will not block the executing thread while waiting for the response to come back.


2 Answers

There is no easy way to do this. URI template variables are usually meant for path elements or a query string parameters. You're trying to pass a host. Ideally, you'd find a better solution for constructing the URI. I suggest Yuci's solution.

If you still want to work with Spring utilities and template expansion, 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);
like image 56
Sotirios Delimanolis Avatar answered Oct 14 '22 20:10

Sotirios Delimanolis


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

like image 35
Yuci Avatar answered Oct 14 '22 19:10

Yuci