<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了Axios+Spring Boot實現檔案上傳和下載的具體程式碼,供大家參考,具體內容如下
前端:Vue + Axios
後端:Springboot + SpringMVC
後端程式碼
只需要使用MultipartFile類配合RequestBody註解即可
@PostMapping("your/path") public ResultData courseCoverUpload(@RequestBody MultipartFile file){ /** your service */ }
前端程式碼
Axios上傳需要設定頭部,使用FormData封裝檔案物件
//file為檔案物件 function upload(file){ //請求頭設定 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正是上傳時的回撥函數,使用方法如下
function uploadFile(param){ //param中的file才是真正的檔案體,用於傳入axios上傳方法的引數 upload( param.file ) },
後端程式碼
將@RequestBody換成==@RequestPart==註解,並再註解中加入接收時的識別key即可同時接受檔案和其他Json引數
@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作資料封裝 let form_data=new FormData(); //此處的key要與後端統一,這裡都使用file form_data.append("file",file_body) //再封裝其他引數時需要使用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); }) }
使用axios下載檔案最噁心之處就在於前後端請求頭還有解析格式要匹配,否則就會出現跨域或者檔案流出錯等問題。
後端程式碼
和返回json資料不同,返回檔案流需要使用HttpServletResponse類的輸出流將檔案流逐一列印出去,這裡選擇用過濾器處理請求,也可以使用Controller
編寫接收前端請求的過濾器
public class FileFilter implements Filter , InputOutputUtil { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { /** 本次後端預設前端使用Get請求進行下載,如若get需要傳遞引數可以用getParameter方式獲取 HttpServletRequest request = (HttpServletRequest) servletRequest; System.out.println(request.getParameter("a")); */ //獲取檔案輸出流,這裡是讀取原生的 File f= new File("file_path"); InputStream inpurStream = new FileInputStream(file); /** 如果檔案資源在其他伺服器上(比如阿里雲的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; //設定返回的頭資訊 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); } //關流操作 outputStream.close(); inputStream.close(); } }
前端程式碼
使用axios的get方法發起請求
function downloadFile(url,param=null){ //設定頭資訊 let config = {responseType:'blob'} //如若前端有引數就加入一下 if (param!=null) config["params"]=param //帶著頭資訊和請求引數發起請求 request.get(url,config).then(res=>{ //如若成功了,開始拆箱 //獲取filename,這裡使用的是正規表示式,關聯 輔助輸出介面 的第9行 let file_name=res.headers["content-disposition"].match(/filename="(S*)"/)[1] //data中裝的是檔案體,需要使用Blob流可以下載 let blob = new Blob([res.data]) //網上最常用的下載方法 let downloadElement = document.createElement('a') let href = window.URL.createObjectURL(blob); //建立下載的連結 downloadElement.href = href; downloadElement.download = file_name; //下載後檔名 document.body.appendChild(downloadElement); downloadElement.click(); //點選下載 document.body.removeChild(downloadElement); //下載完成移除元素 window.URL.revokeObjectURL(href); //釋放blob物件 }) }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45