• springboot+aop+自定义注解,打造通用的全局异常处理和参数校验切面(通用版)


    一.引入相应的maven依赖

    <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>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>


    二.自定义参数校验注解

    /**
    * @Author: guandezhi
    * @Date: 2019/3/11 13:07
    */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface ParamValidate {
    String value() default "";
    }
    

      


    三.自定义异常切面

    package com.gdz.paramvalidate.aspect;
    
    import com.gdz.paramvalidate.annotation.ParamValidate;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;
    import org.springframework.validation.BindingResult;
    import org.springframework.validation.FieldError;
    import org.springframework.validation.ObjectError;
    
    import java.lang.reflect.Method;
    import java.util.List;
    
    /**
    * 异常处理切面
    * @Author: guandezhi
    * @Date: 2019/3/11 13:03
    */
    @Slf4j
    @Aspect
    @Component
    public class ExceptionAspect {
    
    @Before("@annotation(com.gdz.paramvalidate.annotation.ParamValidate)")
    public void before(JoinPoint jp) throws Exception {
    doBefore(jp);
    }
    
    private void doBefore(JoinPoint jp) throws Exception {
    if (getParamValidate(jp) == null) {return;}
    Object[] args = jp.getArgs();
    if (args == null) {return;}
    //将异常格式化成通用格式
    formateException(args); 
    }
    
    private ParamValidate getParamValidate(JoinPoint jp) {
    MethodSignature methodSignature = (MethodSignature) jp.getSignature();
    Method method = methodSignature.getMethod();
    return method.getAnnotation(ParamValidate.class);
    }
    
    private void formateException(Object[] args) throws Exception {
    for (Object arg : args) {
    if (arg instanceof BindingResult) {
    BindingResult result = (BindingResult) arg;
    if (result != null && result.getErrorCount() > 0) {
    List<ObjectError> errors = result.getAllErrors();
    String errorMsg = "";
    for (ObjectError error : errors) {
    if (error instanceof FieldError) {
    FieldError fe = (FieldError) error;
    errorMsg = String.format("%s:%s", fe.getField(), error.getDefaultMessage());
    } else {
    errorMsg = String.format("%s:%s ", error.getCode(), error.getDefaultMessage());
    }
    log.error(errorMsg);
    throw new Exception(errorMsg);
    }
    }
    }
    }
    }
    
    }
    

      


    四.自定义全局异常处理器

    package com.gdz.paramvalidate.exception;
    
    import com.gdz.paramvalidate.bean.ResultVo;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
    * 全局异常处理
    *
    * @Author: guandezhi
    * @Date: 2019/3/11 14:43
    */
    @Slf4j
    @ControllerAdvice
    public class GlobalExceptionHandler {
    
    
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResultVo<Object> handleException(Exception e) {
    String errorMsg = "";
    if (e instanceof NullPointerException) {
    errorMsg = "参数空指针异常";
    } else if (e instanceof HttpMessageNotReadableException) {
    errorMsg = "请求参数匹配错误," + e.getLocalizedMessage();
    } else {
    errorMsg = e.getMessage();
    }
    log.error(String.format("请求异常[%s]", e));
    
    ResultVo<Object> resultVo = new ResultVo<>();
    resultVo.setResultCode("501");
    resultVo.setResultMsg(errorMsg);
    return resultVo;
    }
    }
    其中的resultVo如下:
    
    /**
    * @Author: guandezhi
    * @Date: 2019/3/11 12:14
    */
    @Data
    public class ResultVo<T> {
    
    private String resultCode;
    
    private String resultMsg;
    
    private T data;
    
    }
    

      

    五.在需要校验入参的controller方法上加上自定义注(@ParamValidate)

    /**
    * @Author: guandezhi
    * @Date: 2019/3/11 12:15
    */
    @Slf4j
    @RequestMapping("/user")
    @RestController
    public class UserController {
    
    @ParamValidate
    @RequestMapping("/addUser")
    public String addUser(@RequestBody @Valid User user, BindingResult result) throws Exception {
    int i = 1 / 0;
    return "success";
    }
    }
    

      


    这里必须加上@ParamValidate  @Valid这两个注解才能生效

    其中User类如下:

    /**
    * @Author: guandezhi
    * @Date: 2019/3/11 12:19
    */
    @Data
    public class User {
    
    @NotNull(message = "用户名不能为空")
    private String name;
    
    @NotNull(message = "手机号不能为空")
    private String mobile;
    }
    

      


    六.测试一下

    1.当入参为空值时

     

     
    1.当程序有异常时

     

    代码地址:https://github.com/dezhiguan/GlobalExceptionHandler
    ---------------------
    作者: guandezhi
    来源:CSDN
    原文:https://blog.csdn.net/qq_35859844/article/details/88394376
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    Linux的五个查找命令
    Linux中ftp不能上传文件/目录的解决办法
    linux下的chmod,chown和chgrp
    Memcache基础教程
    Web服务器磁盘满故障
    linux定时任务生产java服务无法执行问题案例
    Linux 用户和用户组管理
    10-xargs 简明笔记
    51-du 显示关于目录层次结构或文件磁盘使用情况的信息
    46-df 显示磁盘空间的使用情况
  • 原文地址:https://www.cnblogs.com/telwanggs/p/10875498.html
Copyright © 2020-2023  润新知