使用RestTemplate大文件上傳,總失敗
環境:
jdk 1.8
springboot v2.2.1.RELEASE
配置:
nginx配置
#參數大小 client_max_body_size 2048M #超時時間 proxy_connect_timeout 600; proxy_read_timeout 600; proxy_send_timeout 600;
項目配置文件配置內容
#單個文件的最大上限 spring.servlet.multipart.max-file-size = 2048MB #單個請求的文件總大小上限 spring.servlet.multipart.max-request-size=2048MB
依然報錯
添加配置類配置restTemplate
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory) { RestTemplate restTemplate = new RestTemplate(factory); restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter()); restTemplate.getMessageConverters().add(new ResourceHttpMessageConverter()); return restTemplate; } @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); //請求工廠類是否應用緩沖請求正文內部,默認值為true, // 當post或者put大文件的時候會造成內存溢出情況,設置為false將數據直接流入底層HttpURLConnection。 factory.setBufferRequestBody(false); factory.setConnectTimeout(150000); factory.setReadTimeout(150000); return factory; } }
代碼中設置: factory.setBufferRequestBody(false);
該代碼的意思是請求工廠類是否應用緩沖請求正文內部,默認值為true,當post或者put大文件的時候會造成內存溢出情況,設置為false將數據直接流入底層HttpURLConnection。
源碼:
/** * Indicate whether this request factory should buffer the * {@linkplain ClientHttpRequest#getBody() request body} internally. * <p>Default is {@code true}. When sending large amounts of data via POST or PUT, * it is recommended to change this property to {@code false}, so as not to run * out of memory. This will result in a {@link ClientHttpRequest} that either * streams directly to the underlying {@link HttpURLConnection} (if the * {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} * is known in advance), or that will use "Chunked transfer encoding" * (if the {@code Content-Length} is not known in advance). * @see #setChunkSize(int) * @see HttpURLConnection#setFixedLengthStreamingMode(int) */ public void setBufferRequestBody(boolean bufferRequestBody) { this.bufferRequestBody = bufferRequestBody; }