前言
本文采用后端从文件服务器下载文件返回byte数组的方式,前端则使用Blob 对象读取byte数组,并使用a标签的download属性对文件进行重命名。解决了通过直链下载文件时,文件服务器默认返回文件名不人性化的问题。
-
解决之前
-
解决之后
1. 后端实现
1.1 实体类XtFile
public class XtFile {
@Id
private String fileId;
private String fileName;
private String filePath;
private String relativePath;
}
1.2 下载文件逻辑
@PostMapping("/download")
public ResponseEntity<byte[]> download(@RequestBody XtFile xtFile, HttpServletRequest request) throws Exception{
String url = xtFile.getFilePath();
HttpHeaders headers = new HttpHeaders();
//通知浏览器以attachment(下载方式)打开
headers.setContentDispositionFormData("attachment",xtFile.getFileName());
//application/octet-stream : 二进制流数据(最常见的文件下载)。
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(IOUtils.toByteArray(getFileInputStream(url)),
headers, HttpStatus.CREATED);
}
private InputStream getFileInputStream(String urlString) {
InputStream is = null;
try {
URL url = new URL(urlString);
// 打开连接
URLConnection con = url.openConnection();
// 输入流
is = con.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
return is;
}
2. 文件下载前端实现
async download (xtFile) {
const { data: bytes } = await this.$http.post('/file/download', xtFile, { responseType: 'blob' })
const downloadLink = document.createElement('a')
// 设置下载文件名
downloadLink.download = xtFile.fileName
downloadLink.style.display = 'none'
const blob = new Blob([bytes])
downloadLink.href = URL.createObjectURL(blob)
document.body.appendChild(downloadLink)
downloadLink.click()
document.body.removeChild(downloadLink)
}
- xtFile参数是上传文件成功时,后端返回的数据,内容包括XtFile实体类的所有属性。