全局异常处理

  • 前言
  • 一、全局异常处理方式一
    • 1.1 自定义全局异常类
    • 1.2 手动抛出异常
    • 1.3 测试打印
  • 二、全局异常处理方式二
    • 2.1 定义基础接口类
    • 2.2 定义枚举类
    • 2.3 自定义异常类
    • 2.4 自定义数据传输
    • 2.5 自定义全局异常处理
    • 2.6 测试代码
  • 总结

前言

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


一、全局异常处理方式一

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

1.1 自定义全局异常类

/*** @description: 自定义异常处理* @author: DT* @date: 2021/4/19 21:17* @version: v1.0*/
@ControllerAdvice
public class MyExceptionHandler {@ExceptionHandler(value =Exception.class)@ResponseBodypublic 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 定义基础接口类

/*** @description: 服务接口类* @author: DT* @date: 2021/4/19 21:39*/
public interface BaseErrorInfoInterface {/***  错误码* @return*/String getResultCode();/*** 错误描述* @return*/String getResultMsg();
}

2.2 定义枚举类

/*** @description: 异常处理枚举类* @author: DT* @date: 2021/4/19 21:41* @version: v1.0*/
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;}@Overridepublic String getResultCode() {return resultCode;}@Overridepublic String getResultMsg() {return resultMsg;}
}

2.3 自定义异常类

/*** @description: 自定义异常类* @author: DT* @date: 2021/4/19 21:44* @version: v1.0*/
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;}@Overridepublic Throwable fillInStackTrace() {return this;}
}

2.4 自定义数据传输

/*** @description: 自定义数据传输* @author: DT* @date: 2021/4/19 21:47* @version: v1.0*/
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;}/*** 成功** @return*/public static ResultResponse success() {return success(null);}/*** 成功* @param data* @return*/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;}@Overridepublic String toString() {return JSONObject.toJSONString(this);}}

2.5 自定义全局异常处理

/*** @description: 自定义异常处理* @author: DT* @date: 2021/4/19 21:51* @version: v1.0*/
@ControllerAdvice
public class GlobalExceptionHandler {private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 处理自定义的业务异常* @param req* @param e* @return*/@ExceptionHandler(value = BizException.class)@ResponseBodypublic ResultResponse bizExceptionHandler(HttpServletRequest req, BizException e){logger.error("发生业务异常!原因是:{}",e.getErrorMsg());return ResultResponse.error(e.getErrorCode(),e.getErrorMsg());}/*** 处理空指针的异常* @param req* @param e* @return*/@ExceptionHandler(value =NullPointerException.class)@ResponseBodypublic ResultResponse exceptionHandler(HttpServletRequest req, NullPointerException e){logger.error("发生空指针异常!原因是:",e);return ResultResponse.error(ExceptionEnum.BODY_NOT_MATCH);}/*** 处理其他异常* @param req* @param e* @return*/@ExceptionHandler(value =Exception.class)@ResponseBodypublic 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;
}


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

/**
* 处理类型转换异常* @param req* @param e* @return*/
@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,大大提高我们的开发效率。

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

  1. Spring Boot项目启动的几种方式

    Spring Boot项目启动的几种方式 方式一:右击启动或者点击intellij右上角的启动按钮 我们访问下浏览器看一下效果 方式二:利用maven启动 我们先进入到项目文件下,然后执行命令   m ...

  2. Spring Boot 2 Webflux的全局异常处理

    Spring Boot 2 Webflux的全局异常处理 参考文章: (1)Spring Boot 2 Webflux的全局异常处理 (2)https://www.cnblogs.com/xiang- ...

  3. Spring Boot 细节挖掘(全局异常处理)

    对于全局异常处理app开发很重要 直接上步骤: 第一创建JsonResult: package com.swaager.swaagerdemo.model;/*** @authorseerhuitao ...

  4. 轻轻松松学习SpringBoot2:第十一篇: Spring Boot项目启动的几种方式

    方式一:右击启动或者点击intellij右上角的启动按钮 我们访问下浏览器看一下效果 方式二:利用maven启动 我们先进入到项目文件下,然后执行命令   mvn spring-boot:run 然后 ...

  5. 【BUG记录】Idea spring boot项目中target中没有同步更新最新目录文件及资源

    BUG 日志 可见是bean创建异常,依赖注入失败 org.springframework.beans.factory.BeanCreationException: Error creating be ...

  6. spring boot 项目源码_Spring Boot2 系列教程(三)理解 Spring Boot 项目中的 parent

    前面和大伙聊了 Spring Boot 项目的三种创建方式,这三种创建方式,无论是哪一种,创建成功后,pom.xml 坐标文件中都有如下一段引用: <parent><groupId& ...

  7. Spring Boot项目介绍(值得学习,超详细)

    目录 1 Spring Boot介绍 2 创建Spring Boot项目 2.1 第一种方式, 使用Spring提供的初始化器, 就是向导创建SpringBoot应用 使用国内的地址 3 注解的使用 ...

  8. STS创建Spring Boot项目实战(Rest接口、数据库、用户认证、分布式Token JWT、Redis操作、日志和统一异常处理)

    STS创建Spring Boot项目实战(Rest接口.数据库.用户认证.分布式Token JWT.Redis操作.日志和统一异常处理) 1.项目创建 1.新建工程 2.选择打包方式,这边可以选择为打 ...

  9. Spring Boot项目(Maven\Gradle)三种启动方式及后台运行详解

    Spring Boot项目三种启动方式及后台运行详解 1 Spring Boot项目三种启动方法 运行Application.java类中的Main方法 项目管理工具启动 Maven项目:mvn sp ...

最新文章

  1. 观察者模式--模拟3D彩票公众号
  2. servlet增删改查实例_SpringMVC4+MyBatis3+SQLServer 2014 整合(包括增删改查分页)
  3. 红帽企业虚拟化平台RHEV中WINDOWS 虚拟机如何安装 GUEST代理和驱动
  4. python 课堂笔记-for语句
  5. 在 Azure App Service 上启用 Application Request Routing
  6. MySQL数据库的安装及环境配置
  7. php 请求header,PHP的curl查看header信息的功能(包括查看返回header和请求header)
  8. 算法64-荷兰国旗问题
  9. 大数据 | 抖音,一款神奇的APP
  10. c++中new是否会自动初始化
  11. mysql b树_为什么 MongoDB 索引选择B树,而 Mysql 选择B+树(精干总结)
  12. 【大疆DJI】安卓开发实习历程- 0.前期准备到面试(HR电话初面+技术一面+技术二面/终面+OC)
  13. 即构推出视频见证系统方案,全面支持泛金融实时双录
  14. 2k分辨率显示器 浏览器_如何使浏览器使用显示器的完整分辨率?
  15. 第26期《Runtime Error可能产生的原因》
  16. Oracle新建的用户看不到表,oracle中用命令行新建的用户没法建表
  17. ad服务器做虚拟化,为虚拟桌面准备AD服务器
  18. Terracotta配置文件
  19. 第七次前端培训(JavaScript)
  20. 无线网络与移动IP技术

热门文章

  1. php 仿电脑桌面系统,EonerCMS——做一个仿桌面系统的CMS(十-附最新源码)
  2. godot python_我的godot开发环境调教记录分享
  3. 信息学奥赛一本通 1979:【18NOIP普及组】龙虎斗 | 洛谷 P5016 [NOIP2018 普及组] 龙虎斗
  4. 信息学奥赛一本通(1251:仙岛求药)
  5. Knight Moves(信息学奥赛一本通-T1450)
  6. 图论 —— 生成树 —— 最小生成树 —— Prim
  7. 玩具谜题(洛谷-P1563)
  8. 骨牌铺方格(HDU-2046)
  9. 数字反转(洛谷-P1307)
  10. 浮点型数据类型存储空间大小(信息学奥赛一本通-T1017)