SpringBoot實(shí)現(xiàn)文件下載功能的方式分享
1. 將文件以流的形式一次性讀取到內(nèi)存,通過響應(yīng)輸出流輸出到前端
/**
* @param path 想要下載的文件的路徑
* @param response
* @功能描述 下載文件:
*/
@RequestMapping("/download")
public void download(String path, HttpServletResponse response) {
try {
// path是指想要下載的文件的路徑
File file = new File(path);
log.info(file.getPath());
// 獲取文件名
String filename = file.getName();
// 獲取文件后綴名
String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
log.info("文件后綴名:" + ext);
// 將文件寫入輸入流
FileInputStream fileInputStream = new FileInputStream(file);
InputStream fis = new BufferedInputStream(fileInputStream);
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 設(shè)置response的Header
response.setCharacterEncoding("UTF-8");
//Content-Disposition的作用:告知瀏覽器以何種方式顯示響應(yīng)返回的文件,用瀏覽器打開還是以附件的形式下載到本地保存
//attachment表示以附件方式下載 inline表示在線打開 "Content-Disposition: inline; filename=文件名.mp3"
// filename表示文件的默認(rèn)名稱,因?yàn)榫W(wǎng)絡(luò)傳輸只支持URL編碼的相關(guān)支付,因此需要將文件名URL編碼后進(jìn)行傳輸,前端收到后需要反編碼才能獲取到真正的名稱
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
// 告知瀏覽器文件的大小
response.addHeader("Content-Length", "" + file.length());
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
outputStream.write(buffer);
outputStream.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}2. 將輸入流中的數(shù)據(jù)循環(huán)寫入到響應(yīng)輸出流中,而不是一次性讀取到內(nèi)存,通過響應(yīng)輸出流輸出到前端
/**
* @param path 指想要下載的文件的路徑
* @param response
* @功能描述 下載文件:將輸入流中的數(shù)據(jù)循環(huán)寫入到響應(yīng)輸出流中,而不是一次性讀取到內(nèi)存
*/
@RequestMapping("/downloadLocal")
public void downloadLocal(String path, HttpServletResponse response) throws IOException {
// 讀到流中
InputStream inputStream = new FileInputStream(path);// 文件的存放路徑
response.reset();
response.setContentType("application/octet-stream");
String filename = new File(path).getName();
response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
ServletOutputStream outputStream = response.getOutputStream();
byte[] b = new byte[1024];
int len;
//從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲在緩沖區(qū)字節(jié)數(shù)組中,讀到末尾返回-1
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b, 0, len);
}
inputStream.close();
}3. 下載網(wǎng)絡(luò)文件到本地
/**
* @param path 下載后的文件路徑和名稱
* @param netAddress 文件所在網(wǎng)絡(luò)地址
* @功能描述 網(wǎng)絡(luò)文件下載到服務(wù)器本地
*/
@RequestMapping("/netDownloadLocal")
public void downloadNet(String netAddress, String path) throws IOException {
URL url = new URL(netAddress);
URLConnection conn = url.openConnection();
InputStream inputStream = conn.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(path);
int bytesum = 0;
int byteread;
byte[] buffer = new byte[1024];
while ((byteread = inputStream.read(buffer)) != -1) {
bytesum += byteread;
System.out.println(bytesum);
fileOutputStream.write(buffer, 0, byteread);
}
fileOutputStream.close();
}4. 網(wǎng)絡(luò)文件獲取到服務(wù)器后,經(jīng)服務(wù)器處理后響應(yīng)給前端
/**
* @param netAddress
* @param filename
* @param isOnLine
* @param response
* @功能描述 網(wǎng)絡(luò)文件獲取到服務(wù)器后,經(jīng)服務(wù)器處理后響應(yīng)給前端
*/
@RequestMapping("/netDownLoadNet")
public void netDownLoadNet(String netAddress, String filename, boolean isOnLine, HttpServletResponse response) throws Exception {
URL url = new URL(netAddress);
URLConnection conn = url.openConnection();
InputStream inputStream = conn.getInputStream();
response.reset();
response.setContentType(conn.getContentType());
if (isOnLine) {
// 在線打開方式 文件名應(yīng)該編碼成UTF-8
response.setHeader("Content-Disposition", "inline; filename=" + URLEncoder.encode(filename, "UTF-8"));
} else {
//純下載方式 文件名應(yīng)該編碼成UTF-8
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
}
byte[] buffer = new byte[1024];
int len;
OutputStream outputStream = response.getOutputStream();
while ((len = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
inputStream.close();
}5. 常見異常和問題
(1)響應(yīng)對象無需通過return返回

原因: 響應(yīng)對象是可以不用作為方法返回值返回的,其在方法執(zhí)行時(shí)已經(jīng)開始輸出,且其無法與@RestController配合,以JSON格式返回給前端


解決辦法: 刪除return語句
(2)返回前端的文件名必須進(jìn)行URL編碼
原因: 網(wǎng)絡(luò)傳輸只能傳輸特定的幾十個字符,需要將漢字、特殊字符等經(jīng)過Base64等編碼來轉(zhuǎn)化為特定字符,從而進(jìn)行傳輸,而不會亂碼
URLEncoder.encode(fileName, "UTF-8")
(3)IO流有待學(xué)習(xí)
1:read() : 從輸入流中讀取數(shù)據(jù)的下一個字節(jié),返回0到255范圍內(nèi)的int字節(jié)值。如果因?yàn)橐呀?jīng)到達(dá)流末尾而沒有可用的字節(jié),則返回-1。在輸入數(shù)據(jù)可用、檢測到流末尾或者拋出異常前,此方法一直阻塞。
2:read(byte[] b) : 從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲在緩沖區(qū)數(shù)組 b 中。以整數(shù)形式返回實(shí)際讀取的字節(jié)數(shù)。在輸入數(shù)據(jù)可用、檢測到文件末尾或者拋出異常前,此方法一直阻塞。如果 b 的長度為 0,則不讀取任何字節(jié)并返回 0;否則,嘗試讀取至少一個字節(jié)。如果因?yàn)榱魑挥谖募┪捕鴽]有可用的字節(jié),則返回值 -1
以上就是SpringBoot實(shí)現(xiàn)文件下載功能的方式分享的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot文件下載的資料請關(guān)注腳本之家其它相關(guān)文章!
- SpringBoot+ruoyi框架文件上傳和下載的實(shí)現(xiàn)
- SpringBoot中的文件上傳和異常處理詳解
- SpringBoot實(shí)現(xiàn)文件上傳下載實(shí)時(shí)進(jìn)度條功能(附源碼)
- SpringBoot簡單實(shí)現(xiàn)文件上傳
- vue+element+springboot實(shí)現(xiàn)文件下載進(jìn)度條展現(xiàn)功能示例
- springboot中Excel文件下載踩坑大全
- springboot單文件下載和多文件壓縮zip下載的實(shí)現(xiàn)
- 在 Spring Boot 項(xiàng)目中實(shí)現(xiàn)文件下載功能
- Spring Boot中進(jìn)行 文件上傳和 文件下載功能實(shí)現(xiàn)
相關(guān)文章
SpringBoot?Security從入門到實(shí)戰(zhàn)示例教程
Spring?Security是一個功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問控制框架,接下來通過本文給大家介紹SpringBoot?Security從入門到實(shí)戰(zhàn)示例教程,感興趣的朋友一起看看吧2022-05-05
理解Java注解及Spring的@Autowired是如何實(shí)現(xiàn)的
今天通過本文帶領(lǐng)大家學(xué)習(xí)注解的基礎(chǔ)知識,學(xué)習(xí)Spring的@Autowired是怎么實(shí)現(xiàn)的,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-07-07
Maven構(gòu)建SpringBoot集成MyBatis過程
文章介紹了如何使用Maven創(chuàng)建一個Spring Boot項(xiàng)目,并集成MyBatis,首先,配置Maven環(huán)境,然后在pom.xml中添加MyBatis依賴,配置數(shù)據(jù)庫連接信息,最后生成Mapper XML文件和DAO層代碼2024-11-11
java中數(shù)組list map三者之間的互轉(zhuǎn)介紹
java中 數(shù)組 list map之間的互轉(zhuǎn)一張圖清晰呈現(xiàn)并附有代碼,不懂的朋友可以參考下2013-10-10
Java中super關(guān)鍵字介紹以及super()的使用
這幾天看到類在繼承時(shí)會用到this和super,這里就做了一點(diǎn)總結(jié),下面這篇文章主要給大家介紹了關(guān)于Java中super關(guān)鍵字介紹以及super()使用的相關(guān)資料,需要的朋友可以參考下2022-01-01
Java Swing中的文本區(qū)(JTextArea)實(shí)現(xiàn)換行保存到文件的幾個方法
這篇文章主要介紹了Java Swing中的文本區(qū)(JTextArea)實(shí)現(xiàn)換行保存到文件的幾個方法,本文給出了4種方法,需要的朋友可以參考下2014-10-10
多數(shù)據(jù)源如何實(shí)現(xiàn)事務(wù)管理
Spring中涉及三個核心事務(wù)處理接口:PlatformTransactionManager、TransactionDefinition和TransactionStatus,PlatformTransactionManager提供事務(wù)操作的基本方法,如獲取事務(wù)、提交和回滾2024-09-09
java開發(fā)中使用IDEA活動模板快速增加注釋的方法
這篇文章主要介紹了java開發(fā)中使用IDEA活動模板快速增加注釋,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
java 從int數(shù)組中獲取最大數(shù)的方法
這篇文章主要介紹了java 從int數(shù)組中獲取最大數(shù)的方法,需要的朋友可以參考下2017-02-02

