自定义注解+springAop实现参数的分组验证

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jingyangV587/article/details/80330147

废话:一个同事写的,感觉很实用,然后我从中整理出来的一个小demo。

问题引入

在日常开发中免不了对传入的参数进行校验,例如更新数据的时候id不能为空,新增数据的时候某个元素不能为空等。我们不得不写类似于下面的代码:

@RequestMapping("/createStudent")
    public Object createStudent( Student student) {
       String name = student.getName();
       if ( StringUtils.isEmpty( name ) ){
         return "姓名不能为空";
      }
        return student;
    }

    @RequestMapping("/updateStudent")
    public Object updateStudent( Student student) {
       String id = student.getId();
       if ( StringUtils.isEmpty( id ) ){
         return "id不能为空";
      }
        return student;
    }

这样确实有很多重复的代码,于是就想着去解决,我把问题简化为下面的小demo,以供参考。

项目结构

这里写图片描述

定义注解用于分组

@Target({ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validate
{
    Class<?>[] groups() default { };
}

定义两个组

public interface Create { }
public interface Update { }

具体逻辑实现(重点)

@Component // 加入到IoC容器
@Aspect // 指定当前类为切面类
public class Aop {
    @Autowired
    protected Validator validator;

    //@Pointcut("@annotation(springboot.Validate)")
    @Pointcut("execution(* springboot.*.*(..))")
    public void pointCut() {

    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 获取当前方法
        Parameter[] parameters = method.getParameters();
        if (parameters != null && parameters.length > 0) {
            for (int j = 0; j < parameters.length; j++) {
                Parameter parameter = parameters[j];
                Validate validate = parameter.getAnnotation(Validate.class);// 获取参数的注解
                if (validate != null) {
                    Object arg = joinPoint.getArgs()[j];// 获取到参数
                    Class<?>[] groups = validate.groups();// 获取注解参数,验证组
                        List<ViolationMessage> violationErrors =groups.length!=0?beanValidator(arg, groups):beanValidator(arg);// 参数有效性验证
                        if (violationErrors != null) {
                            return violationErrors;// 验证不通过,返回结果
                        }
                }
            }
        }

        return joinPoint.proceed();
    }

    public List<ViolationMessage> beanValidator(Object object, Class<?>... groups) {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty()) {
            List<ViolationMessage> list = new ArrayList<>();
            ViolationMessage vm = new ViolationMessage();
            for (ConstraintViolation<Object> cv : constraintViolations) {
                vm = new ViolationMessage();
                vm.setProperty(cv.getPropertyPath().toString());
                vm.setMessage(cv.getMessageTemplate());
                list.add(vm);
            }
            return list;
        }
        return null;
    }

}

原理,利用aop获取获取注解上的分组信息与当前参数,然后用validator进行校验。

实体类

public class Student {
   @NotNull(message="id:不能为空",groups={Update.class})
    @Size(min = 3, max = 20, message = "id长度只能在3-20之间", groups = { Update.class})
    private String id;
    @NotNull(message = "姓名不能为空", groups = {Create.class})
    private String name;
    private String age;
    /**get set省略**/
}

错误信息封装

public class ViolationMessage implements Serializable{

    private static final long serialVersionUID = 1L;

    private String property;
    private String message;
    /**get set省略**/
    }

controller类

@RestController
public class TestController {
    @RequestMapping("/createChack")
    public Object createChack(@Validate(groups={Create.class}) Student student) {
        return student;
    }

    @RequestMapping("/updateChack")
    public Object updateChack(@Validate(groups={Update.class}) Student student) {
        return student;
    }

}

运行SpringbootFirstApplication启动项目进行测试

请求1:http://127.0.0.1:8080/createChack
这里写图片描述
请求2:http://127.0.0.1:8080/updateChack?id=1
这里写图片描述

具体项目见码云:

https://gitee.com/jingyang3877/springboot-param-check

参考博客:

http://www.cnblogs.com/liangweiping/p/3837332.html
https://blog.csdn.net/wangjianwen8016/article/details/50461893
http://www.jb51.net/article/138424.htm
https://blog.csdn.net/littleskey/article/details/52224352

猜你喜欢

转载自blog.csdn.net/jingyangV587/article/details/80330147