本文是精講RestTemplate第6篇,前篇的blog訪問地址如下:
- 精講RestTemplate第1篇-在Spring或非Spring環(huán)境下如何使用
- 精講RestTemplate第2篇-多種底層HTTP客戶端類庫的切換
- 精講RestTemplate第3篇-GET請求使用方法詳解
- 精講RestTemplate第4篇-POST請求方法使用詳解
- 精講RestTemplate第5篇-DELETE行疏、PUT等請求方法使用詳解
RestTemplate是HTTP客戶端庫沃缘,所以為了使用RestTemplate進行文件上傳和下載扰才,需要我們先編寫服務(wù)端的支持文件上傳和下載的程序。請參考我之前寫的一篇文章:SpringBoot實現(xiàn)本地存儲文件上傳及提供HTTP訪問服務(wù) 。按照此文完成學(xué)習(xí)之后蕴忆,可以獲得
- 一個以訪問服務(wù)URI為"/upload”的文件上傳服務(wù)端點
- 服務(wù)端點上傳文件成功后會返回一個HTTP連接,可以用來下載文件茧跋。
下面我們就開始學(xué)習(xí)使用RestTemplate是HTTP客戶端庫慰丛,進行文件的上傳與下載。
一瘾杭、文件上傳
寫一個單元測試類诅病,來完成RestTemplate文件上傳功能,具體實現(xiàn)細節(jié)參考代碼注釋
@SpringBootTest
class UpDownLoadTests {
@Resource
private RestTemplate restTemplate;
@Test
void testUpload() {
// 文件上傳服務(wù)上傳接口
String url = "http://localhost:8888/upload";
// 待上傳的文件(存在客戶端本地磁盤)
String filePath = "D:\\data\\local\\splash.png";
// 封裝請求參數(shù)
FileSystemResource resource = new FileSystemResource(new File(filePath));
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("uploadFile", resource); //服務(wù)端MultipartFile uploadFile
//param.add("param1", "test"); //服務(wù)端如果接受額外參數(shù)粥烁,可以傳遞
// 發(fā)送請求并輸出結(jié)果
System.out.println("--- 開始上傳文件 ---");
String result = restTemplate.postForObject(url, param, String.class);
System.out.println("--- 訪問地址:" + result);
}
}
輸出結(jié)果如下:
--- 開始上傳文件 ---
--- 訪問地址:http://localhost:8888/2020/08/12/028b38f1-3f9b-4088-9bea-1af8c18cd619.png
文件上傳之后贤笆,可以通過上面的訪問地址,在瀏覽器訪問讨阻〗嬗溃或者通過RestTemplate客戶端進行下載。
二钝吮、文件下載
執(zhí)行下列代碼之后埋涧,被下載文件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("文件下載請求結(jié)果狀態(tài)碼:" + rsp.getStatusCode());
// 將下載下來的文件內(nèi)容保存到本地
String targetPath = "D:\\data\\local\\splash-down.png";
Files.write(Paths.get(targetPath), Objects.requireNonNull(rsp.getBody(),
"未獲取到下載文件"));
}
這種下載方法實際上是將下載文件一次性加載到客戶端本地內(nèi)存棘催,然后從內(nèi)存將文件寫入磁盤。這種方式對于小文件的下載還比較適合耳标,如果文件比較大或者文件下載并發(fā)量比較大醇坝,容易造成內(nèi)存的大量占用,從而降低應(yīng)用的運行效率次坡。
三呼猪、大文件下載
這種下載方式的區(qū)別在于
- 設(shè)置了請求頭APPLICATION_OCTET_STREAM,表示以流的形式進行數(shù)據(jù)加載
- RequestCallback 結(jié)合File.copy保證了接收到一部分文件內(nèi)容砸琅,就向磁盤寫入一部分內(nèi)容宋距。而不是全部加載到內(nèi)存,最后再寫入磁盤文件明棍。
@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));
//對響應(yīng)進行流式處理而不是將其全部加載到內(nèi)存中
restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
return null;
});
}
歡迎關(guān)注我的博客乡革,里面有很多精品合集
- 本文轉(zhuǎn)載注明出處(必須帶連接,不能只轉(zhuǎn)文字):字母哥博客。
覺得對您有幫助的話沸版,幫我點贊嘁傀、分享!您的支持是我不竭的創(chuàng)作動力视粮! 细办。另外,筆者最近一段時間輸出了如下的精品內(nèi)容蕾殴,期待您的關(guān)注笑撞。