功能说明:前端导出excel时,后端出现异常,比如sql异常,或者创建excel时出现的异常,希望将这些异常信息返回给前端查看。
框架:vue3 + axios + Springboot
实现难度分析:前端导出excel,axios 需要设置responseType=“blob”, axios的response监听器需要判断后端返回的是否时blob类型,并将整个response返回给axios接口的then(),然而后端我们代码如果正常的情况下,返回的blob,异常情况下,返回的异常信息字符串。
实现代码:
java层:再catch内对response重新定义,并且自定义一个状态码;
@PostMapping("/export")
public void exportFile(@RequestBody map, HttpServletResponse response) {
try {
// todo 导出excel流程代码,最后将workbook 写入到response内 ,如果方法体内调用的自定义函数有try...catch(Exception e)... 需要将异常手动抛到最外层 throw new Exception(e)
} catch(Exception e) {
// 这里接收所有的异常信息
response.setStatus(260); // 定义一个状态码,用于前端的判断,只能是2开头的,其他开头的,到不了前端axios响应拦截器方法体内
response.setContentType("text/plain"); //定义文本类型
response.setCharacterEncoding("UTF-8");
try (PrintWriter out = response.getWriter()){
out.print(e.getMessage()); // 将异常信息写入到response内
}
e.printStackTrace();
}
}
vue 端判断自定义状态码,并做异常信息输出
// 某个导出按钮触发的
const export = () =>{
axios({
url: 'http://xxx/export',
responseType: 'blob',
}).then((response)=>{
if(response.status === 260) {
// 接收前端的异常信息,由于是blob类型,我们需要将blob转文本;
blobToString (new Blob([response.data],{type: 'text/plain'}) ,
(text)=>{
Message.error(text); // 异常信息文本
})
}else {
// todo 将excel blob流下载到浏览器
}
});
}
const blobToString = (blob, callback) => {
let reader = new FileReader();
reader.onload = function(event) {
let text = event.target.result;
callback(text);
};
reader.onerror = function(error) {
console.error('Error reading blob as text:', error);
};
reader.readAsText(blob);
}
axios 响应拦截器
axios.interceptors.response.use((response:AxiosResponse<HttpResponse>)=>{
if(response.config.responseType==="arraybuffer" || response.config.responseType==="blob" || response.data instanceof Blob) {
return response; // 文件流
} else {
//todu 对非文件流请求的统一处理
return response.data;
}
})
2043

被折叠的 条评论
为什么被折叠?



