9. 实战脚手架搭建-全局异常统一处理
因为目前市面上的企业开发模式大都是前后端分离的,就是前端只干前端的活,后端干后端的活,分工明确相互配合。既然要配合就需要一些统一的约定,特别是一些异常信息。因为一些原因系统异常、返回的格式往往不是我们和前后端约定好的格式;这个就需要我们对系统中的异常进行监控,引导到相应的封装方法,对异常信息进行包装返回统一的格式给前端。
在我们学习这节课前,处理的方法是不是在 Controller 层进行 try-catch 然后再 catch 处理异常信息封装格式,但是,Controller 层每个方法体都写一些模板化的 try-catch 的代码,很难看也难维护,特别是还需要对 Service 层的不同异常进行不同处理的时候封装起来更麻烦。
这节课讲解使用 @RestControllerAdvice+ @ExceptionHandler 进行全局的 Controller 层异常处理,这样就可以避免在 Controller 层进行 try-catch 了,我们只需大胆的抛出异常。剩下的交给 @ControllerAdvice + @ExceptionHandler 处理就可以了。
9.1基本使用示例
9.1.1 @RestControllerAdvice
创建一个 RestExceptionHandler 类 加上 @ControllerAdvice 注解
package com.yingxue.lesson.exception.handler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @ClassName: RestExceptionHandler
* 公共异常处理类
* @Author: 小霍
* @UpdateUser: 小霍
* @Version: 0.0.1
*/
@RestControllerAdvice
@Slf4j
public class RestExceptionHandler {
}
9.1.2 @ExceptionHandler
声明一个异常处理的方法
/**
* 系统繁忙,请稍候再试
* @Author: 小霍
* @UpdateUser:
* @Version: 0.0.1
* @param e
* @return com.yingxue.lesson.utils.DataResult<T>
* @throws
*/
@ExceptionHandler(Exception.class)
public <T> DataResult<T> handleException(Exception e){
log.error("Exception,exception:{}", e);
return DataResult.getResult(BaseResponseCode.SYSTEM_BUSY);
}
9.1.3 测试
-
修改 getHome() 方法
@GetMapping("/home") @ApiOperation(value = "测试DataResult接口") public DataResult<String> getHome(){ int i=1/0; DataResult<String> result=DataResult.success("哈哈哈哈测试成功 欢迎来到迎学教育"); return result; }
-
打开浏览器到swagger UI 测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kVg7PXp5-1587573989889)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1567584653084.png)]
9.2 实战中异常封装
在现实实战中,往往我们会在复杂的带有数据库事务的业务中,经常会遇到一些不规则的信息,这个就需要我们后端根据相应的业务抛出相应的运行时异常,进行数据库事务回滚,并希望该异常信息能被返回显示给用户。
3.2.1 自定义运行时异常 BusinessException
-
修改 BusinessException 类加入如下方法
/** * 构造函数 * @param code 异常码 */ public BusinessException(ResponseCodeInterface code) { this(code.getCode(), code.getMsg()); }
-
修改 RestExceptionHandler 加入 封装自定义异常的方法
/** * 自定义全局异常处理 * @Author: 小霍 * @UpdateUser: * @Version: 0.0.1 * @param e * @return com.yingxue.lesson.utils.DataResult<T> * @throws */ @ExceptionHandler(value = BusinessException.class) DataResult businessExceptionHandler(BusinessException e) { log.error("BusinessException,exception:{}", e); return new DataResult(e.getMessageCode(),e.getDetailMessage()); }
-
新增测试主动抛出业务异常接口
@GetMapping("/business/error") @ApiOperation(value = "测试主动抛出业务异常接口") public DataResult<String> testBusinessError(@RequestParam String type){ if(!(type.equals("1")||type.equals("2")||type.equals("3")){ throw new BusinessException(BaseResponseCode.DATA_ERROR); } DataResult<String> result=new DataResult(0,type); return result; }
9.2.2 测试
-
打开浏览器进入swagger ui 找到 测试主动抛出业务异常接口
-
执行测试