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