SpringBoot实现自定义异常+全局异常处理(多个异常处理类catch顺序)【详细步骤+图解】

SpringBoot实现自定义异常+全局异常处理(多个异常处理类catch顺序)【详细步骤+图解】

Java虽然提供了丰富的异常处理类,但是在某些情况下还是不能满足实际需求。


这个时候就必须使用到自定义异常来进行处理,使用自定义异常处理程序错误对用户更加友好,同时对我们自己来说,也可以更加准确地定位到错误,更快地解决。

项目中难免会有被忽略错误,严重的可能会导致系统宕机,所以就需要全局异常处理器来捕获所有异常。


本文将通过几个简单步骤教大家如何实现自定义异常+全局异常处理,废话不多说,直接上步骤。

自定义异常:

  • 首先自定义一个异常类,继承RuntimeException,编写一个构造方法
/**
 * @author ChenTaWen
 * @version 1.0
 */
public class MyException extends RuntimeException {

    /**
     * 异常构造方法 在使用时方便传入错误码和信息
     */
    public MyException(String msg) {
        super(msg);
    }

}
  • 编写测试类,测试自定义异常
/**
 * @author admin
 */
@RestController
@RequestMapping("user")
public class UserLoginController {

    @GetMapping("test")
    public User testLogin() throws MyException {
        throw new MyException("测试自定义异常");
    }
}
  • 使用Postman进行测试
    在这里插入图片描述

全局异常处理:

  • 添加@ControllerAdvice自定义全局异常处理器(注:使用的是lombok的@Slf4j)
/**
 * 全局异常处理器
 *  * @author admin
 */
@Slf4j
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    /**
     * 处理自定义的业务异常
     */
    @ExceptionHandler(value = MyException.class)
    public R<String> bizExceptionHandler(MyException e) {
        log.error("发生业务异常! msg: -> ", e);
        return R.failed(e.getMessage());
    }

    /**
     * 处理空指针的异常
     */
    @ExceptionHandler(value = NullPointerException.class)
    public R<String> exceptionHandler(NullPointerException e) {
        log.error("发生空指针异常! msg: -> ", e);
        return R.failed("发生空指针异常!");
    }

    /**
     * 服务器异常
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R<String> exception(Exception e) {
        log.error("服务器异常! msg: -> ", e);
        return R.failed("服务器异常!");
    }
}
  • 全局异常处理器注解说明
@ExceptionHandler(value = MyException.class) -- 注解类型
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) -- 错误码
@ResponseBody --  返回json
@ControllerAdvice -- 顾名思义,这是一个增强的 Controller。使用这个 Controller ,可以实现三个方面的功能:
1.全局异常处理
2.全局数据绑定
3.全局数据预处理
  • 编写测试类,测试全局异常处理
/**
 * @author admin
 */
@RestController
@RequestMapping("user")
public class UserLoginController {

    @GetMapping("test")
    public User testLogin() {
        throw new NullPointerException("发生空指针异常!");
    }
}
  • 使用Postman进行测试
    在这里插入图片描述

全局参数异常处理器实现数据校验:

  • 自定义全局参数异常处理器
/**
 * 全局参数异常处理器
 *  * @author admin
 */
@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE - 2)
@Slf4j
public class ArgumentsValidateAdvice {
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        log.error("参数异常! msg : -> ", e);
        return R.failed(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }
}
  • 编写一个用户实体类
/**
 * @author admin
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {

    @NotNull(message = "id不能为空")
    private Integer id;

    @NotBlank(message="姓名不能为空")
    @Length(min = 2, max = 4, message = "name 姓名长度必须在 {min} - {max} 之间")
    private String username;

    @NotBlank(message="密码不能为空")
    @Length(min = 5, max = 10, message = "password 密码长度必须在 {min} - {max} 之间")
    private String password;
}
  • 实体类注解说明
@Data -- 参数get()+set()方法
@NoArgsConstructor -- 无参构造方法
@AllArgsConstructor -- 有参构造方法
@validated -- 用来校验数据
@NotNull -- 不能为null
@NotBlank -- 只用于String,不能为null且trim()之后size>0
  • 编写测试类,测试参数异常处理
/**
 * @author admin
 */
@RestController
@RequestMapping("user")
public class UserLoginController {

    @PostMapping("addUser")
    public User addUser(@RequestBody @Validated User user) {
        return user;
    }
}
  • 使用Postman进行测试
    在这里插入图片描述

通常情况下,我们都会定义一个全局异常处理类来处理异常,但是当我们定义了多个异常处理类,我们如何去保证它的执行顺序呢?

可以通过@Order注解来设置处理器的捕获执行顺序,如果没有该注解,他就会使用默认值,也就是Ordered.LOWEST_PRECEDENCE。

越小的优先执行,所以我们只需要在全局参数异常处理器加上@Order(Ordered.LOWEST_PRECEDENCE - 2)就能保证它的执行顺序优先于全局异常处理器。

需要源码可滴滴!
有什么疑问可评论区提问! 求点赞!求转发!求收藏

  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撸码社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值