1. 接口
@GetMapping("/downloadModel/{id}")
@ApiOperation(value = "下载模型")
public void downloadModel(@PathVariable String id, HttpServletResponse response) {
modelService.downloadModel(id, response);
}
2. 逻辑
通过接口id去获取filePath,如:E:\soft\static\model-platform\model\2023-07-24-12-10-03-0010\SK_DaiKeMin@ Idle.fbx
文件名问题请查看:https://blog.csdn.net/u014650759/article/details/77335053
public static void downloadResource(String filePath, HttpServletResponse response) {
// 下载文件名
String downloadName = StringUtils.substringAfterLast(filePath, "/");
// 设置请求头
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=\"" + new String(downloadName.getBytes(), StandardCharsets.UTF_8) + "\"");
response.setHeader("download-filename", downloadName);
// 开放请求头download-filename前端获取权限
response.setHeader("Access-Control-Expose-Headers", "download-filename");
FileInputStream fis = null;
OutputStream os = null;
try {
// 输出
os = response.getOutputStream();
File file = new File(filePath);
if (!file.exists()) {
throw new FileNotFoundException(filePath);
}
fis = new FileInputStream(file);
byte[] b = new byte[1024];
int length;
while ((length = fis.read(b)) > 0) {
os.write(b, 0, length);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
IOUtils.close(os);
IOUtils.close(fis);
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. Vue调用接口实现下载
① 安装file-saver
npm install file-saver@2.0.5 -S
② download.js
import axios from "axios";
import { saveAs } from 'file-saver';
import { Message, MessageBox } from 'element-ui';
const baseURL = process.env.VUE_APP_BASE_URL;
export default {
download(data) {
var url = baseURL + '/model/downloadModel/' + data;
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': localStorage.getItem('token') }
}).then(async (resp) => {
const headers = resp.headers;
let reg = RegExp(/application\/json/);
// 如果是application/json则是后端返回的错误信息
if (headers['content-type'].match(reg)) {
blob2Json(resp.data).then(jsonData => {
if (jsonData.code == 434) {
MessageBox.confirm('登录已过期,请重新登录', '提示', {
confirmButtonText: '确定',
type: 'warning',
showClose: false,
showCancelButton: false,
closeOnClickModal: false,
closeOnPressEscape: false,
}).then(() => {
localStorage.removeItem('token');
localStorage.removeItem('userInfo');
window.location.href = '/';
}).catch(() => {})
} else {
Message.error({message: jsonData.msg});
}
})
} else { // 下载文件
const blob = new Blob([resp.data]);
this.saveAs(blob, decodeURI(resp.headers['download-filename']))
}
})
},
saveAs(text, name, opts) {
saveAs(text,name, opts);
},
}
// 将blob转换成Json
function blob2Json(data) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.readAsText(data);
reader.onload = () => {
let dataResult = reader.result;
const jsonData = JSON.parse(dataResult);
resolve(jsonData);
}
})
}