Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing Content-Length header sending POST request with WebClient (SpringBoot 2.0.2.RELEASE)

I'm using WebClient (SpringBoot 2.0.2.RELEASE) to send a POST with SOAP request, but it is missing "Content-Length" header required by the legacy API.

Is it possible to configure WebClient to include "Content-Length" header? There is an Spring Framework Issue resolved and introduced for EncoderHttpMessageWriter in SpringBoot 2.0.1, but it seems not to work for JAXB.

I tried to use BodyInserters:

webClient.post().body(BodyInserters.fromObject(request)).exchange();

and syncBody:

webClient.post().syncBody(request).exchange();

None of them worked for WebClient. Though, when RestTemplate is used, Content-Length is set and API responds with success

like image 594
Wojciech Marusarz Avatar asked Oct 14 '25 20:10

Wojciech Marusarz


2 Answers

I am struggling with the same problem, as an ugly work-around I am manually serializing the request (JSON in my case) and setting the length (Kotlin code):

open class PostRetrieverWith411ErrorFix(
    private val objectMapper: ObjectMapper
) {

protected fun <T : Any> post(webClient: WebClient, body: Any, responseClass: Class<T>): Mono<T> {
    val bodyJson = objectMapper.writeValueAsString(body)

    return webClient.post()
        .contentType(MediaType.APPLICATION_JSON_UTF8)
        .contentLength(bodyJson.toByteArray(Charset.forName("UTF-8")).size.toLong())
        .syncBody(bodyJson)
        .retrieve()
        .bodyToMono(responseClass)
    }
}
like image 106
Milosz Tylenda Avatar answered Oct 17 '25 18:10

Milosz Tylenda


If you apply Sven's colleague(Max) solution like we did you can also adapt it for cases like your body being a custom obj but you have to serialize it once:

String req = objectMapper.writeValueAsString(requestObject)

and passed that to

webClient.syncBody(req)

Keep in mind that with SpringBoot 2.0.3.RELEASE, if you'll pass a String to webClient as a request, it will put as ContentType header MediaType.TEXT_PLAIN and that made our integration with other service to fail. We fixed that by setting specifically content type header like this:

httpHeaders.setContentType(MediaType.APPLICATION_JSON);
like image 29
brebDev Avatar answered Oct 17 '25 17:10

brebDev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!