前端导出文件时,后端代码出错如何将错误信息返回给前端展示
功能说明:前端导出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;}
})