Issue
I've a Spring Boot 2.2.5 application calling this REST endpoint
@RequestMapping(path = "/usable/search")
public List<Provider> findUsable(
@RequestParam(name = "country-id", required = false) Integer countryId,
@RequestParam(name = "network-ids[]", required = false) List<Integer> networkIds,
@RequestParam(name = "usages[]") Set<Usage> usages)
My caller does
val url = clientUri.toString() + configuration.getUrl().getUseableProvidersForNetworks(); % 'providers/usable/search?'
val builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("usages[]", USAGES)
.queryParam("network-ids[]", networkIds);
val response =
restTemplate.exchange(
builder.toUriString(),
HttpMethod.GET,
entity,
new ParameterizedTypeReference<List<Provider>>() {});
where USAGES
is a Set<Usage>
and networkIds
is a List<Integer>
.
The RestTemplate is created by
RestTemplate eurekaRestTemplate() {
val requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setReadTimeout(TIMEOUT);
requestFactory.setConnectTimeout(TIMEOUT);
return new RestTemplate(new BufferingClientHttpRequestFactory(requestFactory));
}
Problem: The []
get double encoded to %255B%255D
and I end up with a call to
providers/usable/search?usages%255B%255D=MESSAGE_DELIVERY&network-ids%255B%255D=2145118475&network-ids%255B%255D=-1536358371
Which obviously doesn't work; the server misses e.g. usages[]
. It works with curl with []
instead of %255B%255D
.
How can I avoid that?
I'm aware of this issue and the docs, but that didn't help yet.
Solution
The solution was to call UriComponentsBuilder.build(false)
to instruct the UriComponentsBuilder
not to encode the url:
val response = restTemplate.exchange(
builder.build(false).toUriString(),
HttpMethod.GET,
entity,
new ParameterizedTypeReference<List<Provider>>() {});
This is tricky because a test with Mockito/JUnit of this will tell you that the url is not encoded while a test with MockRestServiceServer
will show one level of encoding ([]
become %5B%5D
).
Answered By - Martin Schröder
Answer Checked By - David Marino (JavaFixing Volunteer)