I am using Spring WebClient and Spring Boot 2.3.5.RELEASE to POST a request to a site that wants a Content Type of application/x-www-form-urlencoded. It keeps failing because the Content-Length header is not set. I can set that in the code, but I'm not sure how to compute the Content-Length when the Content-Type is application/x-www-form-urlencoded. The URL I am accessing is a legacy site. I saw this post Missing Content-Length header sending POST request with WebClient (SpringBoot 2.0.2.RELEASE) but it doesn't address the issue for Content-Type=application/x-www-form-urlencoded.
I executed the same request in Postman, and it works fine. In Postman if I remove the Content-Length header I get the same error I see in the code.
Please advise how to compute the Content-Length. Thank you.
Here is a snippet.
final MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("key 1, "value 1");
formData.add("key 2, "value 2");
formData.add("key 3, "value 3");
formData.add("key 4, "value 4");
ResponseEntity<String> resp = webClient
.post()
.uri("https://myurl")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.header(HttpHeaders.CONTENT_LENGTH,
String.valueOf(???))
.body(BodyInserters.fromFormData(formData))
.exchange()
.flatMap(response -> response.toEntity(String.class))
.block();
I have a solution. Turns out that this had nothing to do with Content-Length. I decided to try accessing the same REST endpoint with RestTemplate. I got an identical error where the target endpoint complained about missing parameters. Yet, when I accessed it with Postman or curl it worked perfectly fine.
Instead of using BodyInserters.fromFormData
with a MultiValueMap, I used BodyInserters.fromValue(bodyData)
. For the body data I built a String of values similar to what curl used.
grant_type=client_credentials&client_id=123&client_secret=456&scope=myScope
This issue is perhaps limited to the host serving this API(not a public one), but I found it interesting that RestTemplate and WebClient both failed with a standard approach for x-www-form-urlencoded
, while Postman and curl worked just fine.