内容简介:本文主要为了实现全局异常处理的逻辑,只举简单业务某公司部门需增加员工,处理流程:1先根据员工编号查询员工对象,2判断员工对象是否有信息,即是否不为空,3若有信息,则说明已存在,无需再添加,若不是,则直接添加。代码如下:
-
针对代码中的异常,常规有两种处理方式,一种throws直接抛出,另一种try..catch捕获。
-
在 java 项目中,有可能存在人为逻辑的异常,也可能为取得异常的详情,或是保证程序在异常时继续向下执行,会采用第二种处理方式。
-
但是,代码中每一处异常都来捕获,会使代码什么冗余且不利于维护。
解决思路
-
定义一个全局异常处理类,返回统一规范的异常信息;
-
处理逻辑是,先判定是否会出现异常,再执行后续具体的业务。
业务举例
本文主要为了实现全局异常处理的逻辑,只举简单业务
某公司部门需增加员工,处理流程:1先根据员工编号查询员工对象,2判断员工对象是否有信息,即是否不为空,3若有信息,则说明已存在,无需再添加,若不是,则直接添加。
代码如下:
public class MyService { // 注入dao层 @Autowired EmployeeecMapper employeeecMapper; /** * 添加员工信息 * @param employee 员工对象 * @return 影响的行数 */ public int add(Employee employee) { // 根据id查询员工对象 Employeeec emp = employeeecMapper.selectByPrimaryKey(employee.getId()); // 判断是否已有该员工 if (emp != null){ // 已有,抛出异常,异常信息为已有该员工 throw new RuntimeException("异常代码:1201,错误信息:该员工已存在"); } // 没有,插入该员工 return employeeecMapper.insert(emp); } } 复制代码
异常处理流程
业务中存在运行时异常和业务逻辑异常,前者不运行时很难察觉,后者在遍及业务时就可以定义出来,因此异常分为不可预知异常和可知异常。流程如下:
@ControllerAdvice SpringMVC RuntimeException
可知异常
定义异常信息类,变量为错误代码和错误信息,捕获自定义异常时,直接将该对象返回
不可知异常
定义一个map,将常见的异常存入其中,并定义错误代码。对于其他不常见的异常,即map中没有的,同一一个异常对象返回即可。
异常处理代码流程
可知异常
1、定义打印异常信息与返回结果的接口
public interface ResultCode { // 操作是否成功 boolean success(); // 操作结果代码 long code(); // 提示信息 String message(); } 复制代码
public interface Response { public static final boolean SUCCESS = true; public static final int SUCCESS_CODE = 10000; } 复制代码
2、定义打印异常信息的枚举类和返回结果类
@ToString public enum CommonCode implements ResultCode { NO_PAGE(false,404,"没有信息"), FAIL(false,500,"操作失败!"), SUCCESS(true,200,"操作成功!"); // 结果信息 boolean success; long code; String message; // 带参构造 CommonCode(boolean success, long code, String message) { this.success = success; this.code = code; this.message = message; } @Override public boolean success() { return true; } @Override public long code() { return code; } @Override public String message() { return message; } } 复制代码
@Data @ToString public class ResponseResult implements Response { boolean success = SUCCESS; long code = SUCCESS_CODE; String message; public ResponseResult(ResultCode resultCode){ this.success = resultCode.success(); this.code = resultCode.code(); this.message = resultCode.message(); } } 复制代码
3、定义错误异常类
public class CustomException extends RuntimeException{ @Autowired ResultCode resultCode; // 带参构造 public CustomException(ResultCode resultCode){ this.resultCode = resultCode; } // getter public ResultCode getResultCode(){ return resultCode; } } 复制代码
4、定义异常抛出类
public class ExceptionCast { // 静态方法 public static void cast(ResultCode resultCode){ throw new CustomException(resultCode); } } 复制代码
5、定义异常捕获类,使用 ControllerAdvice
控制器增强的注解,并在捕获CustomException异常的方法上加 ExceptionHandler
注解,即可捕获该类的所有异常,返回json数据。
@ControllerAdvice public class ExceptionCatch { /** * 捕获CustomException类异常 * @param customException * @return 结果信息,json数据 */ @ExceptionHandler(CustomException.class) @ResponseBody public ResponseResult customException(CustomException customException){ ResultCode resultCode = customException.getResultCode(); return new ResponseResult(resultCode); } } 复制代码
6、在业务中抛出异常
public class MyService { @Autowired EmployeeecMapper employeeecMapper; public int add(Employee employee) { Employeeec emp = employeeecMapper.selectByPrimaryKey(employee.getId()); if (emp != null){ ExceptionCast.cast(CommonCode.FAIL); } return employeeecMapper.insert(emp); } } 复制代码
不可知异常处理
1、类似可知异常,先添加错误代码,如
UNAUTHORISE(false,510,"没有权限"), 复制代码
2、在异常捕获类中添加不可知异常的捕获方法。该方法中,定义一个只读的map存储异常类型的错误代码的映射,map中没有的元素,同一用错误代码999来定义。
UNKNOWNERROR(false,999,"未知异常"), 复制代码
@ControllerAdvice public class ExceptionCatch { // 定义map,存贮常见错误信息。该类map不可修改 private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS; // 构建ImmutableMap protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder(); @ExceptionHandler(CustomException.class) @ResponseBody public ResponseResult customException(CustomException customException){ ResultCode resultCode = customException.getResultCode(); return new ResponseResult(resultCode); } /** * 捕获非自定义类异常 * @param exception * @return */ @ExceptionHandler(Exception.class) @ResponseBody public ResponseResult exception(Exception exception){ // 记录日志 LOGGER.error("catch exception ==> ",exception.getMessage()); if (EXCEPTIONS == null){ EXCEPTIONS = builder.build(); } ResultCode resultCode = EXCEPTIONS.get(exception.getClass()); if (resultCode != null){ return new ResponseResult(resultCode); }else { return new ResponseResult(CommonCode.UNKNOWNERROR); } } static { builder.put(HttpMessageNotReadableException.class, CommonCode.INVALID_PARAM); } } 复制代码
完成~~
以上所述就是小编给大家介绍的《SpringBoot之全局异常处理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- SpringBoot(十二):全局异常处理
- Spring Cloud Gateway的全局异常处理
- springboot结合全局异常处理之登录注册验证
- Spring Boot 2 Webflux的全局异常处理
- Laravel 全局异常错误处理源码解析及使用场景
- Spring Boot 2.x(七):全局处理异常
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。