美文网首页
springboot之统一异常处理

springboot之统一异常处理

作者: 陆阳226 | 来源:发表于2020-02-29 17:27 被阅读0次

spring统一异常处理

使用spring的统一异常处理,我们就不再需要在业务代码中就行显式的捕获异常处理,在dao、service、controller层的异常都由spring进行统一的异常捕获处理

基本使用示例

异常处理类

使用@ControllerAdvice注解定义异常处理类,使用@ExceptionHandler匹配具体异常,定义异常处理方法
使用@ResponseBody注解将返回的数据转为json格式,也可以直接使用@RestControllerAdvice代替@ControllerAdvice@ResponseBody
当捕捉到UnknownAccountException异常时返回一个ResultEntity对象,包含错误信息

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
    @ExceptionHandler(UnknownAccountException.class)
    public ResultEntity unknownAccountExceptionHandler(HttpServletRequest request, Exception e) {
        return ResultEntity.error(-1, e.getMessage());
    }
}

自定义异常

简单的自定义异常,只包含异常信息

public class UnknownAccountException extends RuntimeException {
    public UnknownAccountException(String message) {
        super(message);
    }
}

简单的service

servie只简单的抛出自定的异常

@Service
public class LoginService {
    public void login() {
            throw new UnknownAccountException("用户不存在");
    }
}

自定义返回结构

只包含了返回code和信息,用来测试异常处理返回的数据

@Data
public class ResultEntity {
    private int code;
    private String message;

    public static ResultEntity success() {
        ResultEntity resultEntity = new ResultEntity();
        resultEntity.setCode(0);
        resultEntity.setMessage("success");
        return resultEntity;
    }

    public static ResultEntity error(int code, String message) {
        ResultEntity resultEntity = new ResultEntity();
        resultEntity.setCode(code);
        resultEntity.setMessage(message);
        return resultEntity;
    }
}

controller

直接调用service方法抛出异常

@RestController
@RequestMapping("user")
public class UserController {

    private final LoginService loginService;

    public UserController(LoginService loginService) {
        this.loginService = loginService;
    }

    @GetMapping
    public ResultEntity login() {
        loginService.login();
        return ResultEntity.success();
    }
}

返回数据

可以看到返回的是异常捕捉后处理的对象:ResultEntity.error生成的对象

GET http://localhost:8080/user
Content-Type: application/json

{
  "code": -1,
  "message": "用户不存在"
}

如果注释掉controller中抛出异常的方法,返回结果:ResultEntity.sucess生成的对象

GET http://localhost:8080/user
Content-Type: application/json

{
  "code": 0,
  "message": "success"
}

异常匹配的范围

同一个异常被小范围的异常匹配处理方法和大范围的异常匹配处理方法同时覆盖,会选择小范围的异常处理方法
在异常类中增加一个新的异常处理方法,自定义的UnknownAccountExceptionRuntimeException的子类,异常范围更小、更具体,在抛出UnknownAccountException异常时会直接匹配UnknownAccountException的处理方法,忽略掉范围更广的异常处理方法

@ExceptionHandler(RuntimeException.class)
public ResultEntity runtimeExceptionHandler(HttpServletRequest request, Exception e) {
    return ResultEntity.error(-2, "RuntimeException的异常");
}

@ExceptionHandler(Exception.class)
public ResultEntity exceptionHandler(HttpServletRequest request, Exception e) {
    return ResultEntity.error(-2, "Exception的异常");
}

当异常匹配不到具体的异常处理方法时,会去匹配在继承树上离该异常最近的异常的处理方法
注释掉UnknownAccountException的异常处理方法,匹配到了继承树上更近的RuntimeException的处理方法返回的结果

GET http://localhost:8080/user
Content-Type: application/json

{
  "code": -2,
  "message": "RuntimeException的异常"
}

相关文章

网友评论

      本文标题:springboot之统一异常处理

      本文链接:https://www.haomeiwen.com/subject/mxkmhhtx.html