SpringMVC(四)【SSM 整合、统一结果封装、异常处理、前后台协议联调】(2)https://developer.aliyun.com/article/1534218
1.7.4、自定义异常
我们需要建一个包 exception 来专门存放我们自定义的异常,我们每个自定义的异常应该都有自己的编码来标识,方便处理,所以我们需要在 Code 类中再添加编码(越细越好):
系统异常
package com.lyh.exception; // 继承 RuntimeException 之后它就可以自动向上抛 否则我们只能手动 throws public class SystemException extends RuntimeException{ private Integer code; // 帮助识别是哪一种异常 public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public SystemException(Integer code, String message) { super(message); this.code = code; } public SystemException(Integer code,String message, Throwable cause) { super(message, cause); this.code = code; } }
业务异常
package com.lyh.exception; // 继承 RuntimeException 之后它就可以自动向上抛 否则我们只能手动 throws public class BusinessException extends RuntimeException{ private Integer code; // 帮助识别是哪一种异常 public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public BusinessException(Integer code, String message) { super(message); this.code = code; } public BusinessException(Integer code, String message, Throwable cause) { super(message, cause); this.code = code; } }
其它异常
其它异常不用单独定义。
在异常处理器中设置异常处理逻辑
// 这个类必须被 SpringMVC 加载 @RestControllerAdvice public class ProjectExceptionAdvice { @ExceptionHandler(SystemException.class) public Result doSystemException(SystemException e){ // 记录日志 // 发送消息给运维 // 发送邮件给开发人员 // 发送异常给开发人员 return new Result(e.getCode(),null,e.getMessage()); } @ExceptionHandler(BusinessException.class) public Result doBusinessException(BusinessException e){ return new Result(e.getCode(),null,e.getMessage()); } // 其它异常 @ExceptionHandler(Exception.class) public Result doException(Exception e){ // 记录日志 // 发送消息给运维 // 返回给起那段 return new Result(Code.SYSTEM_UNKNOWN_ERR,null,"系统繁忙,请稍后重试"); } }
总结
处理项目异常的步骤:
- 分类(自定义项目系统级、业务级异常)
- 自定义异常编码(越细越好)
- 触发异常(对可能出现异常的代码进行包装,用自定义异常类型抛出去)
- 扫描拦截(定义异常处理器类,这个类必须被控制器扫描,所以最好放到 controller 包下,把抛出的异常交给我们的异常处理器来处理)
1.8、前后端协议联调
1.8.1、环境准备
因为添加了静态资源,SpringMVC会拦截,所有需要在SpringConfig的配置类中将静态资源进行放行。
@Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport { @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/pages/**").addResourceLocations("/pages/"); registry.addResourceHandler("/css/**").addResourceLocations("/css/"); registry.addResourceHandler("/js/**").addResourceLocations("/js/"); registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/"); } }
让 SpringMVC 加载
1.8.2、列表功能(查询所有书籍)
这里前端的东西不多说,Ajax 比较简答,这里只放核心代码:
getAll() { //发送ajax请求 axios.get("/books").then((res)=>{ this.dataList = res.data.data; }); }
测试:
1.8.3、添加功能
打开新增面板:
handleCreate() { this.dialogFormVisible = true; },
增加书籍功能:
handleAdd () { //发送ajax请求 //this.formData是表单中的数据,最后是一个json数据 axios.post("/books",this.formData).then((res)=>{ this.dialogFormVisible = false; this.getAll(); }); }
1.8.4、添加功能状态处理
修改 BookDao 接口的增删改方法的返回值为 int 类型:
修改 BookServiceImpl 实现类的返回值(原本都是不管成功失败返回 true):
设置打开添加表单时清空表单:
resetForm(){ this.formData = {}; } handleCreate() { this.dialogFormVisible = true; this.resetForm(); }
1.8.5、修改功能
//弹出编辑窗口 handleUpdate(row) { // console.log(row); //row.id 查询条件 //查询数据,根据id查询 axios.get("/books/"+row.id).then((res)=>{ if(res.data.code == 20041){ //展示弹层,加载数据 this.formData = res.data.data; this.dialogFormVisible4Edit = true; }else{ this.$message.error(res.data.msg); } }); } // ... handleEdit() { //发送ajax请求 axios.put("/books",this.formData).then((res)=>{ //如果操作成功,关闭弹层,显示数据 if(res.data.code == 20031){ this.dialogFormVisible4Edit = false; this.$message.success("修改成功"); }else if(res.data.code == 20030){ this.$message.error("修改失败"); }else{ this.$message.error(res.data.msg); } }).finally(()=>{ this.getAll(); }); }
1.8.6、删除功能
handleDelete(row) { //1.弹出提示框 this.$confirm("此操作永久删除当前数据,是否继续?","提示",{ type:'info' }).then(()=>{ //2.做删除业务 axios.delete("/books/"+row.id).then((res)=>{ if(res.data.code == 20021){ this.$message.success("删除成功"); }else{ this.$message.error("删除失败"); } }).finally(()=>{ this.getAll(); }); }).catch(()=>{ //3.取消删除 this.$message.info("取消删除操作"); }); }