PUT request with unbuffered RestTemplate

2.6k Views Asked by At

Using Spring RestTemplate, buffer request body set to false and empty body

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
requestFactory.setConnectTimeout(60_000);
RestTemplate restTemplate = RestTemplate(requestFactory);
restTemplate.exchange(uri, HttpMethod.PUT, new HttpEntity<>(httpHeaders), Void.class);

I receive 411 - Length Required status code in response. For some reason Spring RestTemplate does not put Content-Length: 0 header on the request.

In case I comment requestFactory.setBufferRequestBody(false); line, it works perfect. But I need it for sending large files.

UPD: Looking into debug logs showed us, that request doesn't contain Content-Length header.

2

There are 2 best solutions below

0
Michal Foksa On

I managed to replicate your issue with RestTemplate and SimpleClientHttpRequestFactory. After switching to Apache HttpComponents HttpClient the issue is gone.

Here you are how I configured RestTemplate:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

CloseableHttpClient httpClient = HttpClientBuilder
    .create()
    .build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
factory.setBufferRequestBody(false);

RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.exchange(......);

Hope it helps.

0
MaksymT On

I have the same problem. I haven't solved it with RestTemplate. I solved it in such way:

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost uploadFile = new HttpPost("you_url");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
FileBody fileBody = new FileBody(tempFile.toFile(), ContentType.MULTIPART_FORM_DATA, "file_name");
        builder.addPart("parameter_name", fileBody);
        HttpEntity multipart = builder.build();
        uploadFile.setEntity(multipart);

        try (CloseableHttpResponse response = httpClient.execute(uploadFile)) {
            //....
        }