У вас есть вопрос по RestTemplate с большими файлами. Существует ли максимальная длина контента и/или автоматически изменяется, несмотря на то, что он явно установлен?Spring RestTemplate Большие файлы ContentLength Auto Changed
У меня есть файл размером 5 ГБ, который я хочу отправить на мой CDN (Akamai) с помощью команды HTTP PUT. Я установил его, как показано ниже (чтобы избежать ошибок кучи java-пространства), однако я заметил, что при выполнении команды Content-Length изменяется.
@Autowired
@Qualifier("restTemplateUpload")
public void setRestTemplateUpload(RestTemplate restTemplateUpload)
{
this.restTemplateUpload = restTemplateUpload;
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setBufferRequestBody(false);
restTemplateUpload.setRequestFactory(requestFactory);
}
И призыв отправить файл:
Resource resource = new FileSystemResource(localFile);
HttpHeaders headers = new HttpHeaders();
Map<String, String> headerValues = new HashMap<String, String>();
headerValues.put("X-Akamai...", value); //There are more headers, but you can assume this is correctly done as I've been able to transmit smaller files
headerValues.put("Host", host);
headers.setAll(headerValues);
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
//I've tried using this and not using this but the result is
//the same, the request sent changes the value to 1469622184
headers.setContentLength(resource.contentLength());
System.out.println(headers.getContentLength()); //Result is: 5764589480
HttpEntity<Resource> uploadRequest = new HttpEntity<Resource>(resource, headers);
response = restTemplateUpload.exchange(hostPath, HttpMethod.PUT, uploadRequest, String.class);
Charles Proxy сообщает Content-Length 1469622184 и соединение получает убиты, когда запрос достигает этой длины.
Java сообщает об ошибке:
org.springframework.web.client.ResourceAccessException: I/O error on PUT request for "http://hidden.com/path/largefile.txt": too many bytes written;"
EDIT:
еще несколько наблюдений, когда я жёстко Content-Length так: headerValues.put ("Content-Length", «3764589480 «); Поле Content-Length фактически не отправляется, и вместо этого отправляется сообщение Transfer-Encoding: chunked.
Так что я провел несколько тестов, и это то, что происходит:
Запрограммированные Содержание Длина: Результат в Charles
"1064589480": Посылает Content-Length: 1064589480
"2064589480": Посылает Содержание -Длина: 2064589480
"3064589480": Удаляет Content-Length, добавляет Transfer-Encoding: фрагментированное
"3764589480": Удаляет Content-Length, добавляет Transfer-Encoding: фрагментированное
"4294967295": Удаляет Content-Length, добавляет Transfer-Encoding: фрагментированное
"4294967296": Посылает Content-Length: "0", Immediate Краш, слишком много байт написано
"4764589480": Посылает Content-Length: "469622184"
"5764589480": Посылает Content-Length: "1469622184"
насколько я могу вывести, на определенный number, RestTemplate переключится с Content-Len gth к Transfer-Encoding. Как только он пройдет 4294967295, он снова начнет передавать Content-Length до 0. Мое лучшее разрешение для этого - никогда не указывать значение выше 4294967295. Если оно выше этого порога, просто установите его на 4294967295, а RestTemplate изменит его на Кодирование передачи: все равно. Есть ли какие-то проблемы с переполнением/точностью?