首页 > 其他分享 >统一异常处理

统一异常处理

时间:2022-09-03 12:35:47浏览次数:76  
标签:exception return 处理 ExceptionHandler 异常 public BizException 统一

代码托管地址:https://gitee.com/ZomiCC/code/tree/master/exception

此文应用到了[统一校验]部分功能,没有看多可先参考上文:统一校验

统一处理,我们很容易会想到spring中的AOP。没错,本篇文章核心就是使用spring为我们提供的两个注解@RestControllerAdvice + @ExceptionHandler 来实现异常的统一处理。
我们的任务主要分以下几步:

  1. 自定义统一异常类BizException,规范异常类型,便于ExceptionHandler使用
  2. 对controller切面,实现对BindingResult(即调用者请求参数)的统一异常/校验处理,我们称这一步为前置异常捕获
  3. 对service切面,捕获所有的service异常,统一封装为BizException,再返回给controller,方便RestControllerAdvice+ExceptionHandler处理异常类型。我们称这一步为业务异常捕获
  4. 全局异常处理器中,也就是RestControllerAdvice+ExceptionHandler的处理方法中,封装响应结果返回给调用者。

关键代码

依赖包
       <!-- valid校验 -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <!-- 想要BindResult生效,这个依赖一定要有 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!-- aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
统一异常定义
package com.example.exception.exception;

public class BizException extends RuntimeException{
    private String code;
    private String msg;

    public BizException(String code, String msg){
        this.code = code;
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

前置异常捕获
/**
 * 前置异常切面
 */
@Slf4j
@Aspect
@Component
public class ControllerAspect {

    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)" +
            "&&args(..,org.springframework.validation.BindingResult)")
    public void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable{
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (arg instanceof BindingResult) {
                BindingResult result = (BindingResult) arg;
                if (result.hasErrors()) {
                    log.error("请求参数校验错误");
                    FieldError fieldError = result.getFieldError();
                    if (fieldError != null) {
                        //return ResponseUtil.fail(new BizException("111111", fieldError.getDefaultMessage()));
                        throw new BizException("111111", fieldError.getDefaultMessage());
                    }
                    //return ResponseUtil.fail(new BizException("999999", "未知参数错误"));
                    throw new BizException("222222", "未知参数错误┭┮﹏┭┮");
                }
            }
        }
        return joinPoint.proceed();
    }
}
业务异常捕获
/**
 * Service异常捕获,将Service中的所有异常,转换为统一的BizException,方便ExceptionHandler统一处理
 */
@Aspect
public class ServiceAspect {
    @Pointcut("execution(public * com.example.exception.service.*.*(..))")
    public void serviceAspect() {
    }

    @Around("serviceAspect()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            return joinPoint.proceed();
        } catch (Exception e) {
            if (e instanceof BizException) {
                throw e;
            } else {
                throw new BizException("999999", "系统错误^_^");
            }
        }
    }
}
全局异常处理器
package com.example.exception.handler;

import com.example.exception.dto.ResponseEntity;
import com.example.exception.exception.BizException;
import com.example.exception.util.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    /**
     * 业务异常处理
     */
    @ExceptionHandler(BizException.class)
    public ResponseEntity bizExceptionHandler(BizException e) {
        return ResponseUtil.fail(e);
    }

    /**
     * 通用异常处理
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity exceptionHandler(Exception e) {
        log.error(e.getMessage(), e);
        return ResponseUtil.fail("999999", "系统错误(#^.^#)");
    }
}

流程图参考

标签:exception,return,处理,ExceptionHandler,异常,public,BizException,统一
From: https://www.cnblogs.com/zomicc/p/16652254.html

相关文章

  • 统一校验
    此文代码托管地址:https://gitee.com/ZomiCC/code/tree/master/validate我们平时都会碰到很多通用校验的场景:比如字段非空校验、字段长度校验等等。如下所示:@Null:被注......
  • 八--数据处理的两个基本问题
    (1)处理的数据在什么地方?(2)要处理的数据有多长约定reg表示一个寄存器,sreg表示一个段寄存器reg包括:ax、bx、cx、dx、ah、al、bh、bl、ch、cl、dh、dl、sp、bp、si、disreg......
  • 解决:'webpack-dev-server' 不是内部或外部命令,也不是可运行的程序 或批处理文件 根目
    解决:'webpack-dev-server'不是内部或外部命令,也不是可运行的程序或批处理文件根目录删除node_modules文件夹运行“npmrundev”相信很多人在使用webpack-dev-server......
  • statement(not found)异常
    mybatis里的异常statement(notfound)“异常原因是maven工程里默认识别‘resources’包里面的xml,当我们在java包里写的xml则要进行配置”,请看下面步骤启动类要覆盖(@Map......
  • maven如何配置统一依赖多版本共存?
    本来可以通过在groupId后面加点来共存jar包的多版本,就像这样<dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId></dependenc......
  • php exec 函数执行shell命令,中文参数异常的问题
    exec("/usr/local/bin/wkhtmltopdf--page-sizeA4--footer-font-nameFangSong--footer-line--header-font-size13--footer-font-size9--footer-center[page]--......
  • Motion 5 for Mac中文版(视频后期特效处理软件)
    Motion5formac是一款视频效果编辑软件,专为视频编辑人员而设它能让您自定 FinalCutPro 字幕、转场和效果。可帮你便捷地制作影院级的二维、三维和360°字幕,流畅的......
  • selenium元素定位---ElementClickInterceptedException(元素点击交互异常)解决方法
    1、异常原因在编写ui自动化时,执行报错元素无法点击:ElementClickInterceptedException具体报错:selenium.common.exceptions.ElementClickInterceptedException:Message:......
  • SpringMVC异常处理
    基于配置的异常处理SpringMVC提供了一个处理控制器,在方法执行过程中所出现的异常的接口:HandlerExceptionResolver,该接口的实现类有:DefaultHandlerExceptionResolver和Sim......
  • Redis服务端命令请求处理
    命令处理流程1.Redis单线程单进程通过IO复用从文件事件中选出已经就绪的命令放入输入缓存区querybuffer2.一个个取出querybuffer里的命令进行解析,解析argv和argc3.通过a......