Java安全后端返回文件流方式
Java安全后端返回文件流
起由
業(yè)務(wù)流程:上傳文件——服務(wù)器保存文件——根據(jù)路徑訪問文件
這種根據(jù)路徑定位文件,并對文件進行查看的方式對文件安全有很大威脅,一旦知道其他文件的路徑,很有可能會造成文件泄露
改進
所以,當(dāng)前端訪問文件的時候,發(fā)出請求并攜帶token,后端驗證token,確認(rèn)為合法用戶之后,放行
根據(jù)請求路徑執(zhí)行后端的代碼(后端代碼邏輯:根據(jù)路徑讀取文件,輸出文件流,響應(yīng)給前端)
配置文件
配置上存文件的保存路徑
代碼
import org.apache.commons.io.IOUtils; @Value("${file.ectdreport-folder}") private String ectdReportFolder; @Transactional(rollbackFor = Exception.class) public void lookReport(String id, HttpServletResponse response) throws Exception { String url = ectdReportFolder + id + "/file1.html"; File file = new File(url); if (!file.exists()) { throw new Exception("文件不存在");//拋出文件不存在的 } response.setContentType("text/html"); FileInputStream fis = null; OutputStream outputStream = response.getOutputStream(); try { fis = new FileInputStream(file); //將讀取流拷貝到輸出流中 IOUtils.copy(fis, outputStream); //清空緩存的讀取流,保證數(shù)據(jù)完整性 response.flushBuffer(); } catch (IOException e) { e.printStackTrace(); throw new Exception("解析失敗"); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (outputStream != null) { outputStream.close();//輸出流關(guān)閉 } } }
后端返回文件流,前端怎么導(dǎo)出、下載
工作中肯定有很多導(dǎo)出excel、下載文件這種功能。一般都是后端做好,我們?nèi)フ埱髮?yīng)的接口就行了,前端還需要做一些處理就可以實現(xiàn)導(dǎo)出、下載功能了。
第一步:在請求的時候做些一些處理
我們在請求的時候 需要定義responseType【響應(yīng)類型】為blob類型,如果是post請求還需要在請求頭里攜帶Content-Type: 'multipart/form-data'
// 在請求的時候做一些處理 // get請求 markMownLoad = (id) => axios('get',`URLxxxxxx?fileId=${id}`,{ responseType: 'blob', headers:{ 'Content-Type': 'multipart/form-data' } }) // post請求 markMownLoads = (id) => axios('post',`URLxxxxxx?fileId=${id}`,{ responseType: 'blob', headers:{ 'Content-Type': 'multipart/form-data' } })
第二步:向后端發(fā)請求
在請求之前,我們先封裝一個解碼下載的一個方法,方便我們請求成功后調(diào)用
function downLoadXls (res) { const fileNames = res.headers['content-disposition'] if(fileNames) { //解碼 const fileName = decodeURIComponent(fileNames.match(/=(.*)$/)[1]) // 處理返回的文件流 const content =res.data const blob = new Blob([content],{ type: "application/octet-stream; charset=utf-8" }); if('download' in document.createElement('a')) { //非IE下載 const a = document.createElement('a') //創(chuàng)建一個a標(biāo)簽 a.download = fileName //指定文件名稱 a.style.display = 'none' //頁面隱藏 a.href = URL.createObjectURL(blob) // href用于下載地址 document.body.appendChild(a) //插到頁面上 a.click() //通過點擊觸發(fā) URL.revokeObjectURL(a.href) //釋放URL 對象 document.body.removeChild(a) //刪掉a標(biāo)簽 }else{ //IE10 + 下載 navigator.msSaveBlob(blob,fileName) } } }
這個時候發(fā)請求就可以了
// 發(fā)請求 把后端返回的傳過去解碼,然后實現(xiàn)導(dǎo)出、下載 markMownLoads(參數(shù)).then(res => downLoadXls(res))
咱們來看一下后端返回的數(shù)據(jù)時什么樣子的
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java利用EasyExcel解析動態(tài)表頭及導(dǎo)出實現(xiàn)過程
以前做導(dǎo)出功能,表頭和數(shù)據(jù)都是固定的,下面這篇文章主要給大家介紹了關(guān)于Java利用EasyExcel解析動態(tài)表頭及導(dǎo)出實現(xiàn)的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12關(guān)于SpringMVC在Controller層方法的參數(shù)解析詳解
在SpringMVC中,控制器Controller負(fù)責(zé)處理由DispatcherServlet分發(fā)的請求,下面這篇文章主要給大家介紹了關(guān)于SpringMVC在Controller層方法的參數(shù)解析的相關(guān)資料,需要的朋友可以參考下2021-12-12Mybatis?selectKey 如何返回新增用戶的id值
這篇文章主要介紹了Mybatis?selectKey 如何返回新增用戶的id值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01RestTemplate使用Proxy代理作為跳板發(fā)送請求
這篇文章主要為大家介紹了RestTemplate使用代理proxy作為跳板發(fā)送請求的方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2022-03-03基于SpringBoot實現(xiàn)驗證碼功能(兩種驗證碼方式)
這篇文章主要介紹了基于SpringBoot實現(xiàn)驗證碼功能,今天我們介紹的是兩種主流的驗證碼,一種就是進行計算的驗證碼,另外一種就是不需要計算,直接輸入的驗證碼,需要的朋友可以參考下2024-08-08