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); } } } }
分类:
Springboot
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)