Springboot全局异常处理

自定义异常枚举类

枚举类用于定义自定义的异常类型,对应自定义错误码,错误信息,状态码

public enum ErrorCodeEnum {
USERINFO_EXCEPTION(10001,HttpStatus.INTERNAL_SERVER_ERROR,"UserInfo Exception"),
AUTHORIZATION_EXCEPTION(10002,HttpStatus.UNAUTHORIZED,"Authorization Exception"),
FILE_EXCEPTION(10003,HttpStatus.INTERNAL_SERVER_ERROR,"File Exception");
private int code;
private HttpStatus status;
private String msg;
ErrorCodeEnum(int code, HttpStatus status, String msg){
this.code=code;
this.status=status;
this.msg=msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
public HttpStatus getStatus() {
return status;
}
@Override
public String toString() {
return "ErrorCodeEnum{" +
"code=" + code +
", status=" + status +
", msg='" + msg + '\'' +
'}';
}
}

自定义异常类

自定义非受检异常类继承于RuntimeException=>Exceptiom=>Throwable,通过引入枚举类指定异常类型

public class CustomException extends RuntimeException{
private ErrorCodeEnum errorCodeEnum;
private int code;
private String msg;
private HttpStatus status;
public CustomException(ErrorCodeEnum errorCodeEnum){
this.errorCodeEnum=errorCodeEnum;
this.code= errorCodeEnum.getCode();
this.msg= errorCodeEnum.getMsg();
this.status=errorCodeEnum.getStatus();
}
public CustomException(ErrorCodeEnum errorCodeEnum,String additionalMsg){
this(errorCodeEnum);
this.msg=this.msg+':'+additionalMsg;
}
public ErrorCodeEnum getErrorCodeEnum() {
return errorCodeEnum;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
public HttpStatus getStatus() {
return status;
}
//重写父类getMessage方法,便于满足后期不同类型的异常类统一执行getMessage的需求
@Override
public String getMessage() {
return this.msg;
}
}

全局异常处理类

全局异常处理类对全局手动指定的错误类进行捕获,可以在捕获后处理、包装信息返回客户端,也可继续抛出异常通过AOP进行日志记录,也可在不继续抛出异常,返回客户端的同时,通过AOP的方法捕获进行异常信息的日志记录

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
/**
* 异常捕获处理,将异常信息包装于自定义结果类,以json返回给客户端
*/
@ExceptionHandler(CustomException.class)
public ResponseEntity<Result> handleFileException(CustomException ex){
return new ResponseEntity<>(new Result(ex.getCode(), ex.getMsg()),ex.getStatus());
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Result> handlerRuntimeException(RuntimeException ex){
return new ResponseEntity<>(new Result(10000, ex.getClass().getSimpleName()+':'+ex.getMessage()),HttpStatus.INTERNAL_SERVER_ERROR);
}
}

自定义结果类

public class Result {
private int code;
private String msg;
private Map<String,?> data;
public Result(int code,String msg){
this.code=code;
this.msg=msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Map<String, ?> getData() {
return data;
}
public Result setData(Map<String, ?> data) {
this.data = data;
return this;
}
}

在上面的基础上通过AOP切入全局异常处理类,进行异常信息的日志记录

  • 依赖引入

    • pom.xml
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
    <exclusion><!--排除默认日志框架-->
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <!-- Spring AOP -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <!-- log4j2-->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    • 在src/main/resources下新建配置文件log4j2.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <Configuration status="warn">
      <Appenders>
      <!-- 将日志输出到控制台 -->
      <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
      </Console>
      </Appenders>
      <Loggers>
      <Root level="INFO">
      <AppenderRef ref="Console"/>
      </Root>
      </Loggers>
      </Configuration>
    • application.properties

      #logging
      logging.config=classpath:log4j2.xml
  • 全局异常类

    @ControllerAdvice
    @ResponseBody
    public class GlobalExceptionHandler {
    /**
    * 异常处理
    * AOP切入记录异常日志
    */
    @ExceptionHandler(CustomException.class)
    public ResponseEntity<Result> handleFileException(CustomException ex){
    return new ResponseEntity<>(new Result(ex.getCode(), ex.getMsg()),ex.getStatus());
    }
    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<Result> handlerRuntimeException(RuntimeException ex){
    return new ResponseEntity<>(new Result(10000, ex.getClass().getSimpleName()+':'+ex.getMessage()),HttpStatus.INTERNAL_SERVER_ERROR);
    }
    }
  • AOP配置类

    @Aspect
    @Component
    public class ExceptionAspect {
    private static final Logger logger = LogManager.getLogger(ExceptionAspect.class);
    //指定AOP切入的具体包和类
    @Pointcut(value = "execution(* com.example.space.Advice.GlobalExceptionHandler.*(..))")
    public void LogPointcut() {
    }
    //方法执行后触发
    @After("LogPointcut()")
    public void AfterLog(JoinPoint joinPoint) {
    //获取异常方法参数
    Object[] args = joinPoint.getArgs();
    // 获取异常发生的方法和位置信息
    for (Object arg : args) {
    if (arg instanceof RuntimeException) {
    RuntimeException ex = (RuntimeException) arg;
    // 获取异常信息
    String exceptionMessage = ex.getMessage();
    // 获取异常发生的方法和位置信息
    StackTraceElement[] stackTrace = ex.getStackTrace();
    String exceptionMethod = (stackTrace.length > 0) ? stackTrace[0].getMethodName() : "Unknown Method";
    String exceptionLocation = (stackTrace.length > 0) ?
    stackTrace[0].getClassName() + "." + exceptionMethod : "Unknown Location";
    logger.error("Exception in method: " + exceptionLocation + ": " + exceptionMessage);
    }
    }
    }
    }
posted @   chuimber  阅读(139)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示