本文是精講RestTemplate第6篇,前篇的blog訪問地址如下:
- 精講RestTemplate第1篇-在Spring或非Spring環境下如何使用
- 精講RestTemplate第2篇-多種底層HTTP客戶端類別庫的切換
- 精講RestTemplate第3篇-GET請求使用方法詳解
- 精講RestTemplate第4篇-POST請求方法使用詳解
- 精講RestTemplate第5篇-DELETE、PUT等請求方法使用詳解
RestTemplate是HTTP客戶端庫,所以為了使用RestTemplate進行檔案上傳和下載,需要我們先撰寫服務端的支持檔案上傳和下載的程式,請參考我之前寫的一篇文章:SpringBoot實作本地存盤檔案上傳及提供HTTP訪問服務 ,按照此文完成學習之后,可以獲得
- 一個以訪問服務URI為"/upload”的檔案上傳服務端點
- 服務端點上傳檔案成功后會回傳一個HTTP連接,可以用來下載檔案,
下面我們就開始學習使用RestTemplate是HTTP客戶端庫,進行檔案的上傳與下載,
一、檔案上傳
寫一個單元測驗類,來完成RestTemplate檔案上傳功能,具體實作細節參考代碼注釋
@SpringBootTest
class UpDownLoadTests {
@Resource
private RestTemplate restTemplate;
@Test
void testUpload() {
// 檔案上傳服務上傳介面
String url = "http://localhost:8888/upload";
// 待上傳的檔案(存在客戶端本地磁盤)
String filePath = "D:\\data\\local\\splash.png";
// 封裝請求引數
FileSystemResource resource = new FileSystemResource(new File(filePath));
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("uploadFile", resource); //服務端MultipartFile uploadFile
//param.add("param1", "test"); //服務端如果接受額外引數,可以傳遞
// 發送請求并輸出結果
System.out.println("--- 開始上傳檔案 ---");
String result = restTemplate.postForObject(url, param, String.class);
System.out.println("--- 訪問地址:" + result);
}
}
輸出結果如下:
--- 開始上傳檔案 ---
--- 訪問地址:http://localhost:8888/2020/08/12/028b38f1-3f9b-4088-9bea-1af8c18cd619.png
檔案上傳之后,可以通過上面的訪問地址,在瀏覽器訪問,或者通過RestTemplate客戶端進行下載,
二、檔案下載
執行下列代碼之后,被下載檔案url,會被正確的保存到本地磁盤目錄targetPath,
@Test
void testDownLoad() throws IOException {
// 待下載的檔案地址
String url = "http://localhost:8888/2020/08/12/028b38f1-3f9b-4088-9bea-1af8c18cd619.png";
ResponseEntity<byte[]> rsp = restTemplate.getForEntity(url, byte[].class);
System.out.println("檔案下載請求結果狀態碼:" + rsp.getStatusCode());
// 將下載下來的檔案內容保存到本地
String targetPath = "D:\\data\\local\\splash-down.png";
Files.write(Paths.get(targetPath), Objects.requireNonNull(rsp.getBody(),
"未獲取到下載檔案"));
}
這種下載方法實際上是將下載檔案一次性加載到客戶端本地記憶體,然后從記憶體將檔案寫入磁盤,這種方式對于小檔案的下載還比較適合,如果檔案比較大或者檔案下載并發量比較大,容易造成記憶體的大量占用,從而降低應用的運行效率,
三、大檔案下載
這種下載方式的區別在于
- 設定了請求頭APPLICATION_OCTET_STREAM,表示以流的形式進行資料加載
- RequestCallback 結合File.copy保證了接收到一部分檔案內容,就向磁盤寫入一部分內容,而不是全部加載到記憶體,最后再寫入磁盤檔案,
@Test
void testDownLoadBigFile() throws IOException {
// 待下載的檔案地址
String url = "http://localhost:8888/2020/08/12/028b38f1-3f9b-4088-9bea-1af8c18cd619.png";
// 檔案保存的本地路徑
String targetPath = "D:\\data\\local\\splash-down-big.png";
//定義請求頭的接收型別
RequestCallback requestCallback = request -> request.getHeaders()
.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
//對回應進行流式處理而不是將其全部加載到記憶體中
restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
return null;
});
}
歡迎關注我的博客,里面有很多精品合集
- 本文轉載注明出處(必須帶連接,不能只轉文字):字母哥博客,
覺得對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創作動力! ,另外,筆者最近一段時間輸出了如下的精品內容,期待您的關注,
- 《手摸手教你學Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《實戰前后端分離RBAC權限管理系統》
- 《實戰SpringCloud微服務從青銅到王者》
- 《VUE深入淺出系列》
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/83211.html
標籤:Java
