SpringBoot基础教程1.2 异常处理规范

1. 概述

异常处理,在平时业务处理中不可避免;但是,阅读代码最头疼的就是看到一堆try-catch语句,业务逻辑参杂其中,极难维护;那要怎样优雅的处理异常呢?请耐心阅读全文。
2. 不负责任的处理异常

直接抛出异常或遗漏未捕获异常,会怎样?Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面用来展示异常内容

@RestController 
public class BadExceptionController { 
    @GetMapping("/bad") 
    public String bad(){ 
    // todo 业务逻辑 Object object = null; 
    // 模拟空指针异常 object.toString(); return "success"; } 
}

    上述代码极不负责,看看测试结果

    当调用者看到这个结果,估计一脸懵

3. 丑陋的异常处理

    常见的异常处理,在try-catch块中,手动封装返回对应结果;该方法相比上面,虽然封装了异常,但是异常处理逻辑,嵌在业务逻辑中,当要修改业务逻辑时,也不可避免的新增对于异常处理逻辑,耦合度非常高

@RestController
public class UglyExceptionController {

    @GetMapping("/ugly")
    public Map<String, String> ugly(){
        Map<String, String> 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);
    }
}

    创建通用响应处理类

@Data
public class R<T> implements 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添加如下依赖,主要作用是使用注解在编译时生成基础方法

<!--编译时生效-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.20</version>
    <scope>provided</scope>
</dependency>

  

    创建统一异常处理类(重点)

// 如果要验证BadException 和 UglyException请注释@ControllerAdvice

@RestControllerAdvice
public 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

@RestController
public 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. 结束语

说点什么呢,有任何建议,欢迎留言探讨,https://github.com/Mkeeper6/SpringBoot-About
---------------------
作者:Mkeeper
来源:CSDN
原文:https://blog.csdn.net/liu19900205/article/details/80965109
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/qq_40775879/article/details/86221012