Hylton Peimer
Hylton Peimer

Reputation: 648

Springboot 3.2.0 custom RestTemplate doesn't send Content-Length

I have a springboot 3.1.5 application that's I've tried to upgrade to Springboot 3.2.0. This application makes REST calls to another server using a custom RestTemplate. The custom RestTemplate (based on Apache HttpClient 5.2.3) is constructed to ignore SSL certificate verification.

The server that is being invoked returns: 411 Length Required. When adding debug to the springboot 3.2.0 application it seems the "Content-length" header is not being set with springboot 3.2.0. When running Spring 3.1.5, even with the same version of HttpClient, the "Content-Length" is set.

If I send an empty string ("") when there is no body to the post request, this works. Also when I manually serialize objects to String, it works.

Upvotes: 6

Views: 3651

Answers (2)

anubhava
anubhava

Reputation: 786091

Unfortunately BufferingClientHttpRequestFactory works with Spring Boot ver < 3.2.5 only. If one is already on 3.2.5 or above then consider upgrading to Spring Boot 3.3.0 that has fixed this bug.

Upvotes: 3

Hylton Peimer
Hylton Peimer

Reputation: 648

The release notes explain why there is no Content-Length. This was pointed out in the issue: reported issue

Here is my RestTemplate for Springboot 3.2.0 which sets Content-Length:

@Bean
@SneakyThrows
public RestTemplate restTemplate() {

    SSLContext sslContext = SSLContextBuilder.create()
            .loadTrustMaterial((X509Certificate[] certificateChain, String authType) -> true)  // <--- accepts each certificate
            .build();

    Registry<ConnectionSocketFactory> socketRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register(URIScheme.HTTPS.getId(), new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE))
            .register(URIScheme.HTTP.getId(), new PlainConnectionSocketFactory())
            .build();

    HttpClient httpClient = HttpClientBuilder.create()
            .setConnectionManager(new PoolingHttpClientConnectionManager(socketRegistry))
            .setConnectionManagerShared(true)
            .build();

    // Use BufferingClientHttpRequestFactory to ensure Content-Length is added to the request.
    // See https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#web-applications
    // at the end.
    ClientHttpRequestFactory requestFactory = new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));

    return new RestTemplate(requestFactory);

}

The addition of BufferingClientHttpRequestFactory allows Content-Length to be added as a header.

Upvotes: 2

Related Questions