1. 概述
异常处理,在平时业务处理中不可避免;但是,阅读代码最头疼的就是看到一堆try-catch
语句,业务逻辑参杂其中,极难维护;那要怎样优雅的处理异常呢?请耐心阅读全文。
2. 不负责任的处理异常
直接抛出异常或遗漏未捕获异常,会怎样?Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面用来展示异常内容
@RestControllerpublic class BadExceptionController { @GetMapping("/bad") public String bad(){ // todo 业务逻辑 Object object = null; // 模拟空指针异常 object.toString(); return "success"; }}
上述代码极不负责,看看测试结果
当调用者看到这个结果,估计一脸懵
3. 丑陋的异常处理
常见的异常处理,在
try-catch
块中,手动封装返回对应结果;该方法相比上面,虽然封装了异常,但是异常处理逻辑,嵌在业务逻辑中,当要修改业务逻辑时,也不可避免的新增对于异常处理逻辑,耦合度非常高
@RestControllerpublic class UglyExceptionController { @GetMapping("/ugly") public Mapugly(){ Map result = new HashMap<>(); // TODO 直接捕获所有代码块,然后在 cache try { int i = 10 / 0; result.put("code", "200"); result.put("data", "具体返回的结果集"); } catch (Exception e) { result.put("code", "500"); result.put("message", "请求错误"); } return result; }}
4. 优雅的异常处理
创建自定义业务异常类
public class BusinessException extends RuntimeException{ public BusinessException(String message) { super(message); }}
创建通用响应处理类
@Datapublic class Rimplements Serializable { private T data; //服务端数据 private int status = 0; //状态码,0:成功,1:失败 private String msg = ""; //描述信息 public static R isOk() { return new R().msg("成功"); } public static R isFail() { return new R().status(1).msg("失败"); } public static R isFail(Throwable e) { return isFail().msg(e); } public R msg(Throwable e) { this.setMsg(e.toString()); return this; } public R data(T data) { this.setData(data); return this; } public R msg(String msg){ this.setMsg(msg); return this; } public R status(int status) { this.setStatus(status); return this; }}
这里推荐一款神级插件
lombok
,pom.xml
添加如下依赖,主要作用是使用注解
在编译时生成基础方法
org.projectlombok lombok 1.16.20 provided
创建统一异常处理类(重点)
// 如果要验证BadException 和 UglyException请注释@ControllerAdvice@RestControllerAdvicepublic class GlobalExceptionHandler { @ExceptionHandler(value = BusinessException.class) public R businessExceptionHandler(BusinessException exception) { return R.isFail(exception); } @ExceptionHandler(value = Exception.class) public R exceptionHandler(Exception exception) { return R.isFail(exception); }}
@ControllerAdvice
捕获Controller
层抛出的异常,如果添加@ResponseBody
返回信息则为JSON
格式。@RestControllerAdvice
相当于@ControllerAdvice
与@ResponseBody
的结合体。@ExceptionHandler
统一处理一种类的异常,减少代码重复率,降低复杂度。
创建Controller
@RestControllerpublic class BusinessController { @GetMapping("/business/{param}") public R business(@PathVariable String param){ if("ok".equals(param)){ return R.isOk(); } else { throw new BusinessException("business exception: param = " + param); } }}
测试结果如下
5. 工程目录
6. 结束语
说点什么呢,有任何建议,欢迎留言探讨,。
欢迎关注博主公众号:Java十分钟