Axios+Spring?Boot實現(xiàn)文件上傳和下載
本文實例為大家分享了Axios+Spring Boot實現(xiàn)文件上傳和下載的具體代碼,供大家參考,具體內(nèi)容如下
1.所用技術(shù)
前端:Vue + Axios
后端:Springboot + SpringMVC
2.單文件上傳
后端代碼
只需要使用MultipartFile類配合RequestBody注解即可
@PostMapping("your/path") public ResultData courseCoverUpload(@RequestBody MultipartFile file){ ? ? /** ? ? your service ? ? */ }
前端代碼
Axios上傳需要設(shè)置頭部,使用FormData封裝文件對象
//file為文件對象 function upload(file){ ? ? //請求頭設(shè)置 ? ? const header={"Content-type":"multipart/form-data"} ? ? let formData=new FormData(); ? ? //用file作為key沒問題,其他沒試過 ? ? formData.append("file",file); ? ??? ?//這里request封裝過,也可以直接使用axios.post() ?? ?request.post(`path`,formData,{headers:header}).then(res=>{ ? ? ? ? //your serivce ? ? }) }
如若使用element-ui的upload組件,可以選擇自定義上傳方法(好處是可以再請求頭中加入token)
<el-upload ? ? ? class="upload-demo" ? ? ? :auto-upload="false" ? ? ? action ? ? ? :http-request="uploadFile" ? ? ? ref="upload" ? ? ? > ? ? ? ? ? <el-button type="text">點擊上傳</el-button> </el-upload>
上述uploadFile正是上傳時的回調(diào)函數(shù),使用方法如下
function uploadFile(param){ ?? ?//param中的file才是真正的文件體,用于傳入axios上傳方法的參數(shù) ?? ?upload( param.file ) },
3.文件上傳的同時傳輸Json數(shù)據(jù)
后端代碼
將@RequestBody換成==@RequestPart==注解,并再注解中加入接收時的識別key即可同時接受文件和其他Json參數(shù)
@PostMapping("up") public ResultData uploadTest( ?? ?@RequestPart("file") MultipartFile file,? ?? ?@RequestPart("other") Map<String,String> props ?? ?){ ?? ?return ResultData.success().data("file_size",file.getSize()).data("others",props); }
前端代碼
function ?uploadFile(file_body,other_json){ ? ? //頭信息不變 ? ? const header={"Content-type":"multipart/form-data"} ?? ?//依舊用FormData作數(shù)據(jù)封裝 ? ? let form_data=new FormData(); ? ? //此處的key要與后端統(tǒng)一,這里都使用file ? ? form_data.append("file",file_body) ? ? //再封裝其他參數(shù)時需要使用Blob,[]不要錯,type一定要加 ?? ?form_data.append( "other",new Blob([JSON.stringify(other_json)],{type:"application/json"})) ?? ?//這里request封裝過,也可以直接使用axios.post() ? ? request.post(url,form_data,{headers: header}).then(rs=>{ ? ? ? console.log(rs); ? ? }) }
4.文件下載
使用axios下載文件最惡心之處就在于前后端請求頭還有解析格式要匹配,否則就會出現(xiàn)跨域或者文件流出錯等問題。
后端代碼
和返回json數(shù)據(jù)不同,返回文件流需要使用HttpServletResponse類的輸出流將文件流逐一打印出去,這里選擇用過濾器處理請求,也可以使用Controller
編寫接收前端請求的過濾器
public class FileFilter implements Filter , InputOutputUtil { ? ? @Override ? ? public void doFilter(ServletRequest servletRequest, ? ? ? ? ? ? ? ? ? ? ? ? ?ServletResponse servletResponse, ? ? ? ? ? ? ? ? ? ? ? ? ?FilterChain filterChain) throws IOException, ServletException { ? ? ? ? /** 本次后端默認前端使用Get請求進行下載,如若get需要傳遞參數(shù)可以用getParameter方式獲取 ?? ? ? ? ? ?HttpServletRequest request = (HttpServletRequest) servletRequest; ? ? ?? ? ? ?System.out.println(request.getParameter("a")); ? ? ? ? */ ? ? ? ? //獲取文件輸出流,這里是讀取本地的 ? ? ? ? File ?f= new File("file_path"); ? ? ? ? InputStream inpurStream = new FileInputStream(file); ? ? ? ? /** 如果文件資源在其他服務(wù)器上(比如阿里云的OSS),可以用以下代碼獲取文件流 ? ? ? ? URLConnection urlConn = new URL("URL_PATH").openConnection(); ? ? ? ? urlConn.connect(); ? ? ? ? InputStream inputStream = urlConn.getInputStream(); ? ? ? ? */ ? ? ? ?? ? ? ? ? //輸出方法,放在了自己編寫的InputOutputUtil中 ? ? ? ? this.writeFile(servletResponse,"security_key.jpg",inputStream); ? ? } }
輔助輸出的接口
public interface InputOutputUtil { ? ? //輸出文件時用 ? ? default void writeFile(ServletResponse servletResponse, ? ? ? ? ? ? ? ? ? ? ? ? ? ?String fileName,InputStream inputStream) throws IOException { ? ? ? ? HttpServletResponse response = (HttpServletResponse) servletResponse; ? ? ? ? //設(shè)置返回的頭信息 ? ? ? ? response.setContentType("application/octet-stream"); ? ? ? ? response.setCharacterEncoding("UTF-8"); ? ? ? ? response.addHeader("Content-disposition", "attachment;filename=\""+fileName+"\""); ? ? ? ?? ? ? ? ? //跨域處理 ? ? ? ? response.setHeader("Access-Control-Expose-Headers","Content-Disposition"); ? ? ? ? response.setHeader("Access-Control-Allow-Origin","*"); ? ? ? ? response.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE"); ? ? ? ? response.setHeader("Access-Control-Allow-Headers","*"); ? ? ? ? response.setHeader("Access-Control-Max-Age","false"); ? ? ? ? response.setHeader("Access-Control-Allow-Credentials","10"); ? ? ? ?? ? ? ? ? //獲取輸出流 ? ? ? ? ServletOutputStream outputStream=response.getOutputStream(); ? ? ? ? //將文件流逐一放入輸出流中打印給前端 ? ? ? ? byte[] bs1=new byte[1024]; ? ? ? ? int length; ? ? ? ? while((length=inputStream.read(bs1))!=-1){ ? ? ? ? ? ? outputStream.write(bs1,0,length); ? ? ? ? } ? ? ? ? //關(guān)流操作 ? ? ? ? outputStream.close(); ? ? ? ? inputStream.close(); ? ? } }
前端代碼
使用axios的get方法發(fā)起請求
function downloadFile(url,param=null){ ? ? //設(shè)置頭信息 ? ? let config = {responseType:'blob'} ? ? //如若前端有參數(shù)就加入一下 ? ? if (param!=null) config["params"]=param ? ? //帶著頭信息和請求參數(shù)發(fā)起請求 ? ? request.get(url,config).then(res=>{ ? ? ? ? //如若成功了,開始拆箱 ? ? ? ? //獲取filename,這里使用的是正則表達式,關(guān)聯(lián) 輔助輸出接口 的第9行 ? ? ? ? let file_name=res.headers["content-disposition"].match(/filename=\"(\S*)\"/)[1] ? ? ? ? //data中裝的是文件體,需要使用Blob流可以下載 ? ? ? ? let blob = new Blob([res.data]) ? ? ? ?? ? ? ? ? //網(wǎng)上最常用的下載方法 ? ? ? ? let downloadElement = document.createElement('a') ? ? ? ? let href = window.URL.createObjectURL(blob); //創(chuàng)建下載的鏈接 ? ? ? ? downloadElement.href = href; ? ? ? ? downloadElement.download = file_name; //下載后文件名 ? ? ? ? document.body.appendChild(downloadElement); ? ? ? ? downloadElement.click(); //點擊下載 ? ? ? ? document.body.removeChild(downloadElement); //下載完成移除元素 ? ? ? ? window.URL.revokeObjectURL(href); //釋放blob對象 ? ? }) }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- SpringBoot中的文件上傳與下載詳解
- Java實現(xiàn)大文件的分片上傳與下載(springboot+vue3)
- SpringBoot文件上傳與下載功能實現(xiàn)詳解
- Spring?Boot實現(xiàn)文件上傳下載
- SpringBoot上傳和下載文件的原理解析
- SpringBoot 文件或圖片上傳與下載功能的實現(xiàn)
- springboot+vue實現(xiàn)文件上傳下載
- 詳解SpringBoot下文件上傳與下載的實現(xiàn)
- Spring Boot 文件上傳與下載的示例代碼
- SpringBoot 文件上傳和下載的實現(xiàn)源碼
- springboot 中文件上傳下載實例代碼
- SpringBoot實現(xiàn)文件上傳下載功能小結(jié)
- SpringBoot+ruoyi框架文件上傳和下載的實現(xiàn)
相關(guān)文章
JS高級拖動技術(shù) setCapture,releaseCapture
setCapture 的意思就是設(shè)置一個對象的方法被觸發(fā)的范圍,或者作用域。2011-07-07JavaScript時間戳與時間日期間相互轉(zhuǎn)換
今天做項目遇到這樣的問題,要將獲取到的時間轉(zhuǎn)換為時間戳,通過查閱相關(guān)資料,問題順利解決,下面小編把具體實現(xiàn)代碼分享到腳本之家平臺,需要的朋友參考下2017-12-12JavaScript switch case 的用法實例[范圍]
JavaScript switch case 的用法實例,大家可以參考下。2009-09-09微信小程序中的數(shù)據(jù)存儲實現(xiàn)方式
這篇文章主要介紹了微信小程序中的數(shù)據(jù)存儲實現(xiàn)方式,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08JavaScript數(shù)學(xué)對象(Math)方法舉例詳解
這篇文章主要給大家介紹了關(guān)于JavaScript數(shù)學(xué)對象(Math)方法的相關(guān)資料,Math(數(shù)學(xué))對象的作用是執(zhí)行普通的算數(shù)任務(wù),文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-03-03