RestTemplate请求下载文件
时间: 2025-05-10 22:37:29 浏览: 11
### 使用 RestTemplate 实现文件下载
当使用 `RestTemplate` 下载大文件时,如果直接将整个文件加载到内存中,则可能会引发 OutOfMemory (OOM) 错误。为了避免这种情况,可以采用流式处理的方式,逐步读取数据并写入目标文件。
以下是基于流式处理的实现方法:
#### 方法一:通过 InputStreamResource 和 OutputStream 处理
此方法利用了 Spring 提供的 `InputStreamResource` 来避免一次性加载整个文件到内存中。
```java
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileDownloader {
public static void downloadFile(String url, String destinationPath) throws IOException {
RestTemplate restTemplate = new RestTemplate();
// 获取响应头信息
HttpHeaders headers = new HttpHeaders();
ResponseEntity<InputStreamResource> response = restTemplate.getForEntity(url, InputStreamResource.class);
try (InputStream inputStream = response.getBody().getInputStream();
OutputStream outputStream = new FileOutputStream(destinationPath)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
throw new RuntimeException("Failed to write file", e);
}
System.out.println("File downloaded successfully.");
}
}
```
上述代码实现了以下功能:
- 利用 `InputStreamResource` 将远程资源作为输入流获取[^1]。
- 数据被分块读取并通过缓冲区逐块写入本地磁盘[^3]。
---
#### 方法二:手动管理 HTTP 请求和 Response 流
另一种更灵活的方法是直接控制底层的 HTTP 请求和响应流。这种方式绕过了 `RestTemplate` 对字节数组的默认转换逻辑。
```java
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseExtractor;
import org.springframework.web.client.RestTemplate;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class AdvancedFileDownloader {
public static void downloadFile(String url, String destinationPath) throws IOException {
RestTemplate restTemplate = new RestTemplate();
restTemplate.execute(url, HttpMethod.GET, null, new ResponseExtractor<Void>() {
@Override
public Void extractData(ClientHttpResponse response) throws IOException {
try (InputStream inputStream = response.getBody();
OutputStream outputStream = new FileOutputStream(destinationPath)) {
IOUtils.copy(inputStream, outputStream);
}
return null;
}
});
System.out.println("File downloaded successfully using advanced method.");
}
}
```
该方法的特点在于:
- 它允许开发者完全掌控 HTTP 响应流的处理过程[^2]。
- 使用 `IOUtils.copy()` 可简化流复制的操作[^4]。
---
### 注意事项
1. **性能优化**:对于非常大的文件,建议调整 JVM 的堆外内存设置或增加线程池支持以提高并发能力。
2. **错误处理**:在实际应用中需加入异常捕获机制以及重试策略来增强稳定性。
3. **依赖库**:如上例中的 `Apache Commons IO` 是可选工具之一,用于简化 I/O 操作。
---
阅读全文
相关推荐


















