前后端分离架构文件上传与下载(含Vue + Spring完整代码)
本文采用前后端分离式的架构,其中涉及到文件下载的需求,文件下载在任何系统中都是比较常见的。对于前后端分离架构的文件下载与往常的写法有些许不同(试过直接使用a标签,href填上下载地址,发现行不通),所以经过查找与尝试,以下文件下载前后端实现流程供大家参考。
·
一、前言
本文采用前后端分离式的架构,其中涉及到文件下载的需求,文件下载在任何系统中都是比较常见的。对于前后端分离架构的文件下载与往常的写法有些许不同(试过直接使用a标签,href填上下载地址,发现行不通),所以经过查找与尝试,以下文件下载前后端实现流程供大家参考。
二、准备
前端:vue + ViewUI
后端:springboot
三、文件下载
1、准备一个文件下载接口,返回文件流
@GetMapping("/download")
public void downloadFile(HttpServletResponse response) {
// 读取resource目下文件
String templatePath = "classpath:file/test.txt";
String filename = " test.txt ";
File file = null;
try {
file = ResourceUtils.getFile(templatePath);
} catch (FileNotFoundException e) {
log.warn("文件不存在 {}", filename);
// todo, 可以在流中返回“文件不存在“,这样用户可以下载到文件,但是内容为”文件不存在”
return;
}
if (file.isFile()) {
byte[] fileNameBytes = filename.getBytes(StandardCharsets.UTF_8);
filename = new String(fileNameBytes, 0, fileNameBytes.length, StandardCharsets.ISO_8859_1);
response.reset();
response.setContentType("application/force-download");
response.setCharacterEncoding("utf-8");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
byte[] buff = new byte[1024];
OutputStream os = response.getOutputStream();
int i;
while ((i = bis.read(buff)) != -1) {
os.write(buff, 0, i);
os.flush();
}
} catch (IOException e) {
log.error("下载出错 {},错误原因 {}", filename, e.getMessage());
}
} else {
log.warn("文件不存在 {}", filename);
// todo, 可以在流中返回“文件不存在“,这样用户可以下载到文件,但是内容为”文件不存在”
}
}
2、前端定义一个button标签,通过点击按钮实现文件下载
<Button type="text" @click.stop.prevent="downloadFile">下载</Button>
3、下载按钮点击事件
downloadFile (){
let downloadUrl = "/download"
axios({
url: downloadUrl,
method: 'get',
responseType: 'arraybuffer'
}).then(res => {
const blob = new Blob([res.data]);
//创建一个<a></a>标签
let a = document.createElement("a");
// 将流文件写入a标签的href属性值
a.href = URL.createObjectURL(blob);
//设置文件名
a.download = "template.py";
// 隐藏a标签
a.style.display = "none";
// 将a标签追加到文档对象中
document.body.appendChild(a);
// 模拟点击了a标签,会触发a标签的href的读取,浏览器就会自动下载了
a.click();
//用完就删除a标签
a.remove();
})
}
通过以上的做法,就能够在前后端分离架构中实现文件下载啦!
四、文件上传
1、后端准备一个上传文件接口
@PostMapping("/upload")
public Boolean uploadFile(FileVO fileVO) throws Exception {
String location = "D:\\file";
String user = "001";
// 创建存放文件目录,一个用户一个目录
File dir = Paths.get(location, user).toFile();
if (!dir.isDirectory()) {
boolean mkdirs = dir.mkdirs();
if (!mkdirs) {
log.error("脚本文件保存目錄創建失敗,目录:{}", dir);
return false;
}
// 保存脚本文件
MultipartFile file = fileVO.getFile();
try {
file.transferTo(Paths.get(location, user, file.getOriginalFilename()));
} catch (Exception e) {
log.error("脚本文件: {} 保存失敗,錯誤原因: {}", file.getOriginalFilename(), e.getMessage());
return false;
}
return true;
}
}
public class ScriptVO {
/**
*文件
*/
private MultipartFile file;
}
2、定义一个上传标签,通过点击按钮实现文件上传(如果不是使用ViewUI,那么请使用对应前端框架提供的标签)
<div>
<Upload
:before-upload="handleUpload"
type="drag">
<div style="padding: 20px 0">
<Icon type="ios-cloud-upload" size="52" style="color: #3399ff"></Icon>
<p>点击或拖拽选择Python脚本文件</p>
</div>
</Upload>
</div>
<div>
<Button
type="primary"
style="margin-left: 8px;"
@click="submit"
>确认</Button>
</div>
3、上传按钮点击事件
handleUpload (file) {
this.uploadFile = file;
return false;
},
submit(){
const formData = new FormData();
formData.append("file", uploadFile);
axios.post('/upload',formData,{
'Content-type' : 'multipart/form-data'
}).then(res=>{
res = res.data
// 上传成功后的处理
if (res == true) {
// 上传成功
}
else {
// 上传失败
}
})
}
通过以上的做法,就能够在前后端分离架构中实现文件上传啦!
更多推荐
已为社区贡献1条内容
所有评论(0)