springboot全局异常处理器stater

一、目的:

在分布式系统中,定义一个全局异常处理器stater,其它微服务只需要引入依赖即可。

为了方便维护错误信息,因此将错误信息封装到一个枚举中。

为了封装异常处理代码,因此将所有接口的异常处理封装到了springmvc的 ControllerAdvice 中。

二、代码实现:

1、引入依赖:

        <!--spring的全局异常处理器也是一个controller,需要相关依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

2、新建一个接口:

public interface IException {
    public int getCode();
    public String getMessage();
}

3、新建一个枚举类:

@NoArgsConstructor
@AllArgsConstructor
public enum ExceptionEnum implements IException {

    NOT_FIND(404, "查询失败"),
    ;

    int code;
    String message;


    @Override
    public int getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

4、新建一个自定义异常类:

error方法可同时记录日志和向上抛异常

@Data
public class MyException extends RuntimeException {
    private Integer errorCode;
    private String errorMessage;

    public MyException (IException iException) {
        this.errorCode = iException.getCode();
        this.errorMessage = iException.getMessage();
    }

    public static void error(Logger logger, IException e,Exception source) {
        logger.error("异常码[{}],异常提示[{}],异常详情:",
                e.getCode(), e.getMessage(),source);
        throw new MyException (e);
    }
    public static void error(Logger logger, IException e) {
        logger.error("异常码[{}],异常提示[{}]",
                e.getCode(), e.getMessage());
        throw new MyException (e);
    }
}

5、全局异常处理器(处理逻辑较为简单,仅供参考):

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity<Map<String,Object>> exceptionHandler(Exception e, HttpServletRequest request){
        log.error("Global Exception Occured => url : {}", request.getRequestURL());
        //打印完成错误信息,方便调试
        e.printStackTrace();
        //检测是否是自定义异常,如果是响应详细信息
        if(e instanceof EgoException){
            EgoException exception=(EgoException) e;
            //利用Map实现VO(也可以自定义VO)
            Map<String, Object> resultVO = new HashMap<>(2);
            resultVO.put("errorCode", exception.getErrorCode());
            resultVO.put("errorMessage", exception.getErrorMessage());
            //将具体错误信息响应给客户端
            return ResponseEntity.status(exception.getErrorCode()).body(resultVO);
        }

        // 如果不是,直接返回500
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }

}

6、新增自动配置文件GlobalExceptionHandlerAutoConfiguration

@Configuration
public class GlobalExceptionHandlerAutoConfiguration {
    @Bean
    public GlobalExceptionHandler globalExceptionHandler() {
        return new GlobalExceptionHandler();
    }
}

7、新增resouces/META-INF/spring.factories,内容如下:

#值为自定义的自动配置文件路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.test.exception.GlobalExceptionHandlerAutoConfiguration

8、记录日志:

        引入依赖:

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

        新建文件logback-spring.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--输出日志格式-->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                <!--%d - %msg%n-->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </pattern>
        </layout>
    </appender>
    <!--只保存info日志-->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </pattern>
        </encoder>
        <!--滚动输出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>d:/logs/info/info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--只保存warn日志-->
    <appender name="fileWarnLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </pattern>
        </encoder>
        <!--滚动输出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>d:/logs/warn/warn.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--只保存error日志-->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
        <!--滚动输出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>d:/logs/error/error.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <root level="info">
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileWarnLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>

</configuration>

9、使用时,在其它模块中引入此模块依赖,业务代码如下:

try{
...
}
catch (Exception e) {
   MyException.error(log,ExceptionEnum.BRAND_NOT_FOUND,e);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值