Spring Boot项目优雅的全局异常处理方式(全网最新)

前言

在日常项目开发中,异常是常见的,但是如何更高效的处理好异常信息,让我们能快速定位到BUG,是很重要的,不仅能够提高我们的开发效率,还能让你代码看上去更舒服,SpringBoot的项目已经对有一定的异常处理了,但是对于我们开发者而言可能就不太合适了,因此我们需要对这些异常进行统一的捕获并处理。


一、全局异常处理方式一

SpringBoot中,@ControllerAdvice 即可开启全局异常处理,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用@ExceptionHandler注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。

1.1 自定义全局异常类

@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(value =Exception.class)
    @ResponseBody
    public String exceptionHandler(Exception e){
        System.out.println("全局异常捕获>>>:"+e);
        return "全局异常捕获,错误原因>>>"+e.getMessage();
    }
}

1.2 手动抛出异常

 @GetMapping("/getById/{userId}")
public CommonResult<User> getById(@PathVariable Integer userId){
    
    int a = 10/0;
    return CommonResult.success(userService.getById(userId));
}

1.3 测试打印

在这里插入图片描述
在这里插入图片描述
很显然这样的用户体验效果是极差的,虽然这种能够让我们知道异常的原因,但是在很多的情况下来说,可能还是不够人性化,不符合我们的要求。

二、全局异常处理方式二

2.1 定义基础接口类

public interface BaseErrorInfoInterface {

    
    String getResultCode();

    
    String getResultMsg();
}

2.2 定义枚举类

public enum ExceptionEnum implements BaseErrorInfoInterface{
    
    
    SUCCESS("2000", "成功!"),
    BODY_NOT_MATCH("4000","请求的数据格式不符!"),
    SIGNATURE_NOT_MATCH("4001","请求的数字签名不匹配!"),
    NOT_FOUND("4004", "未找到该资源!"),
    INTERNAL_SERVER_ERROR("5000", "服务器内部错误!"),
    SERVER_BUSY("5003","服务器正忙,请稍后再试!");

    
    private final String resultCode;

    
    private final String resultMsg;

    ExceptionEnum(String resultCode, String resultMsg) {
        this.resultCode = resultCode;
        this.resultMsg = resultMsg;
    }

    @Override
    public String getResultCode() {
        return resultCode;
    }

    @Override
    public String getResultMsg() {
        return resultMsg;
    }
}

2.3 自定义异常类

public class BizException extends RuntimeException{

    private static final long serialVersionUID = 1L;

    
    protected String errorCode;
    
    protected String errorMsg;

    public BizException() {
        super();
    }

    public BizException(BaseErrorInfoInterface errorInfoInterface) {
        super(errorInfoInterface.getResultCode());
        this.errorCode = errorInfoInterface.getResultCode();
        this.errorMsg = errorInfoInterface.getResultMsg();
    }

    public BizException(BaseErrorInfoInterface errorInfoInterface, Throwable cause) {
        super(errorInfoInterface.getResultCode(), cause);
        this.errorCode = errorInfoInterface.getResultCode();
        this.errorMsg = errorInfoInterface.getResultMsg();
    }

    public BizException(String errorMsg) {
        super(errorMsg);
        this.errorMsg = errorMsg;
    }

    public BizException(String errorCode, String errorMsg) {
        super(errorCode);
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public BizException(String errorCode, String errorMsg, Throwable cause) {
        super(errorCode, cause);
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }


    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    @Override
    public Throwable fillInStackTrace() {
        return this;
    }
}

2.4 自定义数据传输

public class ResultResponse {
    
    private String code;

    
    private String message;

    
    private Object result;

    public ResultResponse() {
    }

    public ResultResponse(BaseErrorInfoInterface errorInfo) {
        this.code = errorInfo.getResultCode();
        this.message = errorInfo.getResultMsg();
    }

    public String getCode() {
        return code;
    }

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

    public String getMessage() {
        return message;
    }

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

    public Object getResult() {
        return result;
    }

    public void setResult(Object result) {
        this.result = result;
    }

    
    public static ResultResponse success() {
        return success(null);
    }

    
    public static ResultResponse success(Object data) {
        ResultResponse rb = new ResultResponse();
        rb.setCode(ExceptionEnum.SUCCESS.getResultCode());
        rb.setMessage(ExceptionEnum.SUCCESS.getResultMsg());
        rb.setResult(data);
        return rb;
    }

    
    public static ResultResponse error(BaseErrorInfoInterface errorInfo) {
        ResultResponse rb = new ResultResponse();
        rb.setCode(errorInfo.getResultCode());
        rb.setMessage(errorInfo.getResultMsg());
        rb.setResult(null);
        return rb;
    }

    
    public static ResultResponse error(String code, String message) {
        ResultResponse rb = new ResultResponse();
        rb.setCode(code);
        rb.setMessage(message);
        rb.setResult(null);
        return rb;
    }

    
    public static ResultResponse error( String message) {
        ResultResponse rb = new ResultResponse();
        rb.setCode("-1");
        rb.setMessage(message);
        rb.setResult(null);
        return rb;
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }

}

2.5 自定义全局异常处理

@ControllerAdvice
public class GlobalExceptionHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    
    @ExceptionHandler(value = BizException.class)
    @ResponseBody
    public ResultResponse bizExceptionHandler(HttpServletRequest req, BizException e){
        logger.error("发生业务异常!原因是:{}",e.getErrorMsg());
        return ResultResponse.error(e.getErrorCode(),e.getErrorMsg());
    }

    
    @ExceptionHandler(value =NullPointerException.class)
    @ResponseBody
    public ResultResponse exceptionHandler(HttpServletRequest req, NullPointerException e){
        logger.error("发生空指针异常!原因是:",e);
        return ResultResponse.error(ExceptionEnum.BODY_NOT_MATCH);
    }

    
    @ExceptionHandler(value =Exception.class)
    @ResponseBody
    public ResultResponse exceptionHandler(HttpServletRequest req, Exception e){
        logger.error("未知异常!原因是:",e);
        return ResultResponse.error(ExceptionEnum.INTERNAL_SERVER_ERROR);
    }
}

2.6 测试代码

@PostMapping("/add")
public boolean add(@RequestBody User user) {
    
    if(user.getName()==null){
        throw  new BizException("-1","用户姓名不能为空!");
    }
    return true;
}

在这里插入图片描述

 @PutMapping("/update")
public boolean update(@RequestBody User user) {
    
    String str = null;
    str.equals("111");
    return true;
}

在这里插入图片描述

 @DeleteMapping("/delete")
public boolean delete(@RequestBody User user)  {
    
    Integer.parseInt("abc123");
    return true;
}

在这里插入图片描述
如果我们想捕获这个类型转换异常,是不是再添加一个遗产处理方法就可了。
在这里插入图片描述

@ExceptionHandler(value = NumberFormatException.class)
@ResponseBody
public ResultResponse exceptionHandler(HttpServletRequest req, NumberFormatException e){
    logger.error("发生类型转换异常!原因是:",e);
    return ResultResponse.error(ExceptionEnum.PARAMS_NOT_CONVERT);
}

PARAMS_NOT_CONVERT("4002","类型转换不对!"),

在这里插入图片描述
自定义全局异常处理除了可以处理上述的数据格式之外,也可以处理页面的跳转,只需在新增的异常方法的返回处理上填写该跳转的路径并不使用ResponseBody 注解即可。

总结

异常处理,能够减少代码的重复度和复杂度,有利于代码的维护,并且能够快速定位到BUG,大大提高我们的开发效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目详细功能参考项目演示内容即可项目优势:1、项目从零开始到完结 附带视频,源码以及相关辅助资料,适合学习使用,项目也可拿来即用。2、几乎全手写代码,功能流程详细 跟着可以独立完成,附带详细代码相关常见bug 和 调试解决方案,让大家学会跟踪快速解决问题。3、系统后端使用LayUI技术,对页面不精通的小伙伴也可以快速完成精美页面的设计及应用,支持统一后台管理,也可拿来做其他项目通用后台4、针对layui 相关技术点薄弱的学员提供相关技术点学习,让快速上手完成项目研发5、选材来自生活,项目真实感强,可用学习使用和就业面试使用,适合作为面试中提高实际项目经验...6、该项目前后端分离,满足前沿技术点..项目技术栈:- 数据库:MySQL8.0- 后端技术:SpringBoot,MyBatisPlus,JWT 等- 日志技术:Log4j- 数据库连接池:druid- 前端技术:LayUI, axios,Echarts,Ztree 等- Web容器:Apache Tomcat 9- 项目管理工具:Maven3.6- 思维导图设计工具:XMIND 8- 开发工具: IDEA2020, WebStorm2020- 数据库设计软件:Power Designer16.5特别提示:1、涉及相关技术点学习,更多侧重大学生或无项目经验以及项目经验较少的学员入门到项目完结项目实战2、项目中功能处理大多提供多种解决方式,如跨域访问,更多让大家了解解决方式的同时学会技术点应用3、加入bug的调试以及代码跟踪处理,更好的让学员更多学会如何解决问题

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值