最近刚工作,有一个视频下载的需求,在查询一些文章后,解决了这个问题。所以,在这里简单记录一下。参考文章在最后。
后端:
Controller层
@RestController
@RequestMapping("/download")
public class Download{
@GetMapping("/downloadVideo")
public void downloadVideo(@RequestParam String fileName,@RequestParam String url,HttpServletResponse response) throws IOException {
//验证参数合法性
if(StrUtil.isEmpty(url)){
System.out.println("路径错误");
return;
}
File file = new File(url);
//验证文件是否存在
if (!file.exists() || file.isDirectory()) {
System.out.println("文件不存在");
return;
}
//创建一个文件输入流,用于读取文件内容
FileInputStream fis = new FileInputStream(file);
//设置响应头,指示浏览器以附件形式下载文件,并设置下载文件名为‘fileName’
response.setHeader("content-disposition","attachment;filename="+fileName);
//获取响应的输出流,用于将文件内容写入响应体。
ServletOutputStream sos = response.getOutputStream();
//创建一个8KB的缓冲区,用于读取文件内容。
byte[] buffer = new byte[1024*8];
int len = 0;
//循环读取文件内容到缓冲区,直到文件读取完。
while((len = fis.read(buffer)) != -1){
sos.write(buffer,0,len);
}
//关闭文件输入流,释放资源。
fis.close();
}
}
前端
页面中下载按钮绑定的方法
//record是使用了ant-design-vue中的table组件,获取了那一行的数据
downloadVideo(record){
//这里的url之后可以换成视频所在服务器地址
downloadFile('/download/downloadVideo',record.fileName,{url:"E:\\A_JNTP_MieHuoJi\\视频素材\\地铁.mp4",fileName:record.fileName})
},
文件下载方法
/**
* 下载文件
* @param url 文件路径
* @param fileName 文件名
* @param parameter
* @returns {*}
*/
export function downloadFile(url, fileName, parameter) {
return downFile(url, parameter).then((data) => {
//如果没有内容返回,下载失败
if (!data || data.size === 0) {
Vue.prototype['$message'].warning('文件下载失败')
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
//兼容IE浏览器
window.navigator.msSaveBlob(new Blob([data]), fileName)
} else {
//Blob构造函数将数据包装成Blob对象,createObjectURL方法生成一个临时URL来引用这个Blob对象。
let url = window.URL.createObjectURL(new Blob([data]))
//创建一个隐藏的<a>元素,用于触发下载。
let link = document.createElement('a')
//将链接元素设置为隐藏。
link.style.display = 'none'
//设置链接的href属性为之前生成的Blob URL。
link.href = url
//设置链接的download属性,以便指定下载文件的名称。
link.setAttribute('download', fileName)
//将链接元素添加到DOM中。
document.body.appendChild(link)
//模拟点击链接,触发下载。
link.click()
document.body.removeChild(link) //下载完成移除元素
window.URL.revokeObjectURL(url) //释放掉blob对象
}
})
}
axios请求 这里是用了我自己封装好的axios。
/**
* 下载文件
* @param url
* @param parameter
* @returns {*}
*/
export function downFile(url,parameter){
return axios({
url: url,
params: parameter,
method:'get' ,
responseType: 'blob' //这个很重要
})
}
responseType:'blob'的使用场景和作用
1.文件下载
当你希望从服务器下载一个文件(例如图片、视频、文档等)并在客户端处理时,设置responseType: 'blob'是必要的。这样客户端会将响应数据解析为Blob对象,而不是默认的字符串或JSON。
2.处理二进制数据
对于需要处理二进制数据的场景,例如显示图片、播放视频,或者上传下载文件等,Blob类型的数据非常合适,因为它能够表示不可变的、原始数据的类文件对象。
参考文章:cloud.tencent.com/developer/a…
本文部分内容源自chatGPT,只做参考学习,愿各位大佬指点。