Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebClient encoding queryParams spring

I have trouble with WebClient encoding query parameters when the value of one parameter is decoded JSON value to String.

One of queryParams value is :

[ { "var": "report_days", "op": "=", "val": "7" } ]

it is decoded from HTTP method : ?filter=%5B%7B%22var%22%3A%22report_days%22%2C%22op%22%3A%22%3D%22%2C%22val%22%3A%227%22%7D%5D. So decoding to MultiMap<String, String> is executed correctly, but in uriBuilder the exception is thrown.

return webClient.get()
  .uri(uriBuilder -> uriBuilder.path("/nodes/last").queryParams(queryParams).build()) //Problem
  .header(HttpHeaders.AUTHORIZATION, token)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .bodyToMono(String.class)
  .log();

Exception:

java.lang.IllegalArgumentException: Not enough variable values available to expand '"var"'
2021-11-22T11:17:38.252421700Z  at org.springframework.web.util.UriComponents$VarArgsTemplateVariables.getValue(UriComponents.java:370)
2021-11-22T11:17:38.252461800Z  Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
2021-11-22T11:17:38.252492300Z Error has been observed at the following site(s):
2021-11-22T11:17:38.252521200Z  *__checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
2021-11-22T11:17:38.252586100Z  *__checkpoint ⇢ HTTP GET "/nodeNew/all/last_protected?filter=%5B%7B%22var%22%3A%22report_days%22%2C%22op%22%3A%22%3D%22%2C%22val%22%3A%227%22%7D%5D" [ExceptionHandlingWebHandler]
2021-11-22T11:17:38.252628200Z Stack trace:
2021-11-22T11:17:38.252666300Z      at org.springframework.web.util.UriComponents$VarArgsTemplateVariables.getValue(UriComponents.java:370)
2021-11-22T11:17:38.252699800Z      at org.springframework.web.util.HierarchicalUriComponents$QueryUriTemplateVariables.getValue(HierarchicalUriComponents.java:1087)
2021-11-22T11:17:38.252723100Z      at org.springframework.web.util.UriComponents.expandUriComponent(UriComponents.java:263)
2021-11-22T11:17:38.252738600Z      at org.springframework.web.util.HierarchicalUriComponents.lambda$expandQueryParams$5(HierarchicalUriComponents.java:450)
2021-11-22T11:17:38.252754400Z      at java.base/java.util.Map.forEach(Map.java:713)

Maybe is some of configuration to solve it? In queryParams might be another values but not in JSON format, so I would like to avoid do it in that way (that works now, but it have to forward all queryParams not only key "filter"):

return webClient.get()
  .uri(uriBuilder -> uriBuilder.path("/nodes/last").queryParam(URLEncoder.encode(queryParams.getFirst("filter"), StandardCharsets.UTF_8)).build())
like image 514
kamilguti Avatar asked Aug 30 '26 05:08

kamilguti


1 Answers

I came across with the same trouble recently and this did the job:

  • Create a method that returns a copy of webclient with a custom DefaultUriBuilderFactory
public WebClient getWebclientNoEncoded() {
    DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(this.baseUrl); //Here comes your base url
    factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
    return this.webClient.mutate()
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .uriBuilderFactory(factory)
        .build();
}

And then in the client method:

apiClient.getWebclientNoEncoded()
            .get()
            .uri(uriBuilder -> uriBuilder
                .path("/foo")
                .queryParam(UriUtils.encodeQueryParam(myJsonString, StandardCharsets.UTF_8.toString()))
                .build())
            .header(HttpHeaders.AUTHORIZATION, bearerToken)
            .retrieve()

PD. Sorry about my poor english.

like image 104
kenuchi Avatar answered Aug 31 '26 20:08

kenuchi