SpringBoot2.x统一异常捕获@RestControllerAdvice

今天主要给大家介绍以下传统项目中如何解决代码中存在的大量try....catch...代码问题。在传统的项目框架中,我们不可避免的会遇到程序抛出异常的情况,有些异常不会影响程序的正常运行,而有些异常则是致命的,经常会导致我们的项目宕机。而为了尽可能的避免这种情况,我们一般会对代码进行异常捕获处理,这就造成代码中会存在大量的异常捕获代码try....catch...,这使得我们的代码易读性及美观性都相当的差。今天就给大家介绍以下如何捕获全局异常,从而避免对每一次请求进行异常捕获。

话不多说,上代码::

  1. 首先我们希望我们的接口每次返回的数据都是一定的格式的,这样前端访问接口就可以直观的了解接口的可用性。所以我们新建类ResultBean来作为统一返回接口的Bean
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ResultBean {

    private Integer code; //执行编号
    private String message; //返回信息
    private Object data; //封装内容

}
  1. 其次,我们不同的接口返回的异常也是不尽相同的,所以我们新建枚举类ResultEnum来定义我们的返回类型。
public enum ResultEnum {

    SUCCESS(200,"操作成功"),

    FAIL(500,"操作失败"),

    EXCEPTION(400,"系统错误"),

    NOPERMISS(401,"用户没有权限");

    private Integer code;
    private String message;

    private ResultEnum(Integer code,String message){
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

  1. 当然我们需要自己的异常处理类MyException
public class MyException extends Exception {

    private Integer code;

    public MyException(String msg){
        super(msg);
    }

    public MyException(Integer code,String msg){
        super(msg);
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}
  1. 接下来就是今天的重点了@RestControllerAdvice@ExceptionHandler进行异常捕获处理
@RestControllerAdvice
public class ExceptionAdvice {

    private static Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultBean defaultException(Exception e){
        logger.error("系统发生异常:{},请及时处理!",e.getMessage());
        if(null != e.getMessage()){
            if(e.getMessage().contains("Subject does not have permission")){
                return ResultBean.builder()
                        .code(ResultEnum.NOPERMISS.getCode())
                        .message(ResultEnum.NOPERMISS.getMessage())
                        .build();
            }
            return ResultBean.builder()
                    .code(ResultEnum.EXCEPTION.getCode())
                    .message(ResultEnum.EXCEPTION.getMessage())
                    .build();
        }
        return ResultBean.builder()
                .code(ResultEnum.EXCEPTION.getCode())
                .message("空指针异常")
                .build();
    }

    @ExceptionHandler(value = MyException.class)
    @ResponseBody
    public ResultBean myException(MyException e){
        e.printStackTrace();
        Integer code = e.getCode();
        String message = e.getMessage();

        if(null == e.getCode()){
            code = ResultEnum.EXCEPTION.getCode();
        }

        if (null == e.getMessage()){
            message = ResultEnum.EXCEPTION.getMessage();
        }

        return ResultBean.builder()
                .code(code)
                .message(message)
                .build();
    }

}
  1. 为了以后的使用方便,我们可以编写自己的返回信息封装工具类ResultUtil
public class ResultUtil {

    /**
     * 返回错误信息
     * @param message 错误信息
     * @return
     */
    public static ResultBean error(String message){
        return ResultBean.builder()
                .code(ResultEnum.FAIL.getCode())
                .message(message)
                .build();
    }

    /**
     * 返回错误信息
     * @param code 错误编码
     * @param message 错误信息
     * @return
     */
    public static ResultBean error(Integer code,String message){
        return ResultBean.builder()
                .code(code)
                .message(message)
                .build();
    }

    /**
     * 返回错误信息
     * @param resultEnum 枚举类
     * @return
     */
    public static ResultBean error(ResultEnum resultEnum){
        return ResultBean.builder()
                .code(resultEnum.getCode())
                .message(resultEnum.getMessage())
                .build();
    }

    /**
     * 返回错误信息
     * @return
     */
    public static ResultBean error(){
        return ResultBean.builder()
                .code(ResultEnum.FAIL.getCode())
                .message(ResultEnum.FAIL.getMessage())
                .build();
    }

    /**
     * 返回操作成功信息
     * @param message 枚举类
     * @return
     */
    public static ResultBean success(String message){
        return ResultBean.builder()
                .code(ResultEnum.SUCCESS.getCode())
                .message(message)
                .build();
    }

    /**
     * 返回操作成功信息
     * @param code 成功编号
     * @param message 成功信息
     * @return
     */
    public static ResultBean success(Integer code,String message){
        return ResultBean.builder()
                .code(code)
                .message(message)
                .build();
    }

    /**
     * 返回操作成功信息
     * @param resultEnum 枚举类
     * @return
     */
    public static ResultBean success(ResultEnum resultEnum){
        return ResultBean.builder()
                .code(resultEnum.getCode())
                .message(resultEnum.getMessage())
                .build();
    }

    /**
     * 返回操作成功信息
     * @return
     */
    public static ResultBean success(){
        return ResultBean.builder()
                .code(ResultEnum.SUCCESS.getCode())
                .message(ResultEnum.SUCCESS.getMessage())
                .build();
    }

    /**
     * 返回操作成功信息
     * @return
     */
    public static ResultBean success(Object data){
        return ResultBean.builder()
                .code(ResultEnum.SUCCESS.getCode())
                .message(ResultEnum.SUCCESS.getMessage())
                .data(data)
                .build();
    }

    /**
     * 返回操系统异常信息
     * @param message 枚举类
     * @return
     */
    public static ResultBean exception(String message){
        return ResultBean.builder()
                .code(ResultEnum.EXCEPTION.getCode())
                .message(message)
                .build();
    }

    /**
     * 返回操系统异常信息
     * @param resultEnum 枚举类
     * @return
     */
    public static ResultBean exception(ResultEnum resultEnum){
        return ResultBean.builder()
                .code(resultEnum.getCode())
                .message(resultEnum.getMessage())
                .build();
    }

    /**
     * 返回操系统异常信息
     * @return
     */
    public static ResultBean exception(){
        return ResultBean.builder()
                .code(ResultEnum.EXCEPTION.getCode())
                .message(ResultEnum.EXCEPTION.getMessage())
                .build();
    }

}

至此,我们的全局异常捕获及统一接口返回就实现完成了

大家可以编写测试Controoller进行测试

@PostMapping("/login")
    @ResponseBody
    public Object login(String username, String password){
        if(StringUtils.isEmpty(username)){
            return ResultUtil.error("用户名为空");
        }

        if(StringUtils.isEmpty(password)){
            return ResultUtil.error("密码为空");
        }
        
        /**
        * 登录业务流程
		*/
        return  ResultUtil.success("登录成功");
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序小达人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值