首页 > 其他分享 >Springboot全局异常处理

Springboot全局异常处理

时间:2023-11-23 10:11:05浏览次数:37  
标签:code return Springboot ex msg 全局 异常 public String

自定义异常枚举类

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

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);
                }
    
            }
    
        }
    }
    

标签:code,return,Springboot,ex,msg,全局,异常,public,String
From: https://www.cnblogs.com/chuimber/p/17850945.html

相关文章

  • 使用SpringBoot实现文件的上传
    使用SpringBoot实现文件的上传springboot可以直接使用org.springframework.web.multipart.MultipartFile所以非常容易实现一、首先是简单的单文件上传先在index.html页面下写一个简单的form表单<h1>单文件</h1><formclass="form-signin"th:action="@{/SingleFile/upload}"......
  • 微服务 Gateway 网关——全局过滤器
     代码步骤: ①网关模块里创建一个类并实现GlobalFilter接口  @Order(-1)//值越小,优先级越高。也可以实现Ordered接口指定优先级@Component//注入到Spring容器publicclassAuthorizeFilterimplementsGlobalFilter{@OverridepublicMono<Void>filt......
  • springboot如何监控各种指标?
    以springboot2.7.17为例: 1:新增如下依赖:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency> 然后,在你的配置文件(如 application.properties)中添加以下配......
  • springboot tomcat连接数监控
     直接问文心一言:  ......
  • Python全局解释器锁GIL机制
    全局解释器锁GlobalInterpreterLock,CPython在解释器级别的一把锁,叫GIL全局解释器锁。程序编译成字节码,程序想跑多线程,但是GIL保证CPython进程中,同一时刻只能有一个线程执行字节码。所以,哪怕是在多CPU的情况下,即使每个线程恰好调度到了每个CPU上,有了这把大锁,同时只能有一个CPU......
  • 全局样式和资源字典
    全局样式和资源字典在解决方案中添加资源字典buttonStytle,最好自定义个文件夹放里边。如图:资源字典中写样式,注意基样式可以有key可以无key。<ResourceDictionaryxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schem......
  • 3种Sentinel自定义异常,你用过几种?
    SpringCloudAlibabaSentinel是目前主流并开源的流量控制和系统保护组件,它提供了强大的限流、熔断、热点限流、授权限流和系统保护及监控等功能。使用它可以轻松的保护我们微服务,在高并发环境下的正常运行。那么,当程序触发了限流和熔断规则时,如何自定义返回的异常信息呢?这是......
  • springboot去除内嵌tomcat
    springboot去除内嵌tomcat步骤在pom文件中加入以下代码点击查看代码<!--多模块排除内置tomcat--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> ......
  • SpringBoot + Vue实现分页查询
    后端在controller层修改SpringBoot自带分页查询方法,只需要修改关键代码就可以@GetMapping("/findAll/{page}/{size}")//获取url输入的页码publicPage<Users>findAll(@PathVariable("page")intpage,@PathVariable("size")intsize){//将页码取到方法内P......
  • 基于springboot的校园失物招领系统-计算机毕业设计源码+LW文档
    校园失物招领系统介绍在现代大学校园中,失物招领系统是一个至关重要的组成部分,旨在为学生、教职员工和访客提供便捷的失物招领服务。本文将介绍一个基于SpringBoot的校园失物招领系统,该系统结合了现代技术和用户友好的界面,提供了高效、安全和快速的失物招领流程。系统架构该系统采......