项目中的统一异常处理

目录

1:异常处理

1.1:异常问题分析

1.2:统一异常处理实现

1.2.1:全局异常处理器

1.2.2:自定义异常类

1.2.3:统一响应前端异常信息封装类

1.2.4:通用的异常信息枚举类

1.2.5:测试 


1:异常处理

1.1:异常问题分析

在service方法中有很多的参数合法性校验,当参数不合法则抛出异常,下边我们测试下异常处理。

请求创建课程基本信息,故意将必填项设置为空。

测试发现报500异常,如下:

 返回这样错误的信息的在客户端展示显然是不行的。

问题:并没有输出我们抛出异常时指定的异常信息。

所以,现在我们的需求是当正常操作时按接口要求返回数据,当非正常流程时要获取异常信息进行记录,并提示给用户。

异常处理除了输出在日志中,还需要提示给用户,前端和后端需要作一些约定:

1、错误提示信息统一以json格式返回给前端。

2、以HTTP状态码决定当前是否出错,非200为操作异常。

如何规范异常信息?

代码中统一抛出项目的自定义异常类型,这样可以统一去捕获这一类或几类的异常。

规范了异常类型就可以去获取异常信息。

如果捕获了非项目自定义的异常类型统一向用户提示“执行过程异常,请重试”的错误信息。

如何捕获异常?

代码统一用try/catch方式去捕获代码比较臃肿,可以通过SpringMVC提供的控制器增强类统一由一个类去完成异常的捕获。

如下图:

1.2:统一异常处理实现

根据上边分析的方案,统一在base基础工程实现统一异常处理,各模块依赖了base基础工程都 可以使用。

首先在base基础工程添加需要依赖的包:

Java
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

1.2.1:全局异常处理器

 从 Spring 3.0 - Spring 3.2 版本之间,对 Spring 架构和 SpringMVC 的Controller 的异常捕获提供了相应的异常处理。

  • @ExceptionHandler
  • Spring3.0提供的标识在方法上或类上的注解,用来表明方法的处理异常类型。
  • @ControllerAdvice
  • Spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强,        在项目中来增强SpringMVC中的Controller。通常和@ExceptionHandler 结合使用,来处理SpringMVC的异常信息。
  • @ResponseStatus
  • Spring3.0提供的标识在方法上或类上的注解,用状态代码和应返回的原因标记方法或异常类。
    调用处理程序方法时,状态代码将应用于HTTP响应。
/**
 * @author 爱吃豆的土豆
 * @version 1.0
 * @description TODO
 * @date 2023/2/12 17:01
 */
@Slf4j
@ControllerAdvice
//@RestControllerAdvice
public class GlobalExceptionHandler {

 //对项目的自定义异常类型进行处理
   @ResponseBody
   @ExceptionHandler(XueChengPlusException.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
 public RestErrorResponse customException(XueChengPlusException e){

    //记录异常
    log.error("系统异常{}",e.getErrMessage(),e);
    //..

    //解析出异常信息
    String errMessage = e.getErrMessage();
    RestErrorResponse restErrorResponse = new RestErrorResponse(errMessage);
    return restErrorResponse;
   }


   @ResponseBody
   @ExceptionHandler(Exception.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
 public RestErrorResponse exception(Exception e){

    //记录异常
    log.error("系统异常{}",e.getMessage(),e);

    //解析出异常信息
    RestErrorResponse restErrorResponse = new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrorMessage());

    return restErrorResponse;
   }
}

1.2.2:自定义异常类


/**
 * @author 爱吃豆的土豆
 * @description 本项目自定义异常类型
 */
public class XueChengPlusException extends RuntimeException {

    private String errMessage;

    public XueChengPlusException() {
    }

    public XueChengPlusException(String message) {
        super(message);
        this.errMessage = message;

    }

    public String getErrMessage() {
        return errMessage;
    }

    public void setErrMessage(String errMessage) {
        this.errMessage = errMessage;
    }

    /**
     * 传入自定义异常信息
     * @param message
     */
    public static void cast(String message){
        throw new XueChengPlusException(message);
    }
    /**
     * 重载了一下方法,调用规定好的枚举异常类中的信息
     * @param error
     */
    public static void cast(CommonError error){
        throw new XueChengPlusException(error.getErrorMessage());
    }
}

1.2.3:统一响应前端异常信息封装类

/**
 * @author 爱吃豆的土豆
 * @version 1.0
 * @description 和前端约定返回的异常信息模型
 * @date 2023/2/12 16:55
 */
public class RestErrorResponse implements Serializable {

 private String errMessage;

 public RestErrorResponse(String errMessage){
  this.errMessage= errMessage;
 }

 public String getErrMessage() {
  return errMessage;
 }

 public void setErrMessage(String errMessage) {
  this.errMessage = errMessage;
 }
}

1.2.4:通用的异常信息枚举类

/**
 * @Author 爱吃豆的土豆、
 * @Date 2023/4/22 15:44
 * @desc 系统执行过程中出现的异常信息
 */
public enum CommonError {
    UNKOWN_ERROR("执行过程异常,请重试。"),
    PARAMS_ERROR("非法参数"),
    OBJECT_NULL("对象为空"),
    QUERY_NULL("查询结果为空"),
    REQUEST_NULL("请求参数为空");

    private String errorMessage;

     CommonError(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
}

1.2.5:测试 

猜你喜欢

转载自blog.csdn.net/m0_64550837/article/details/130306414