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

废话:一个同事写的,感觉很实用,然后我从中整理出来的一个小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/all-examples/blob/master/jingyang3877-springboot-param-check-master.zip

参考博客:

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
https://blog.csdn.net/weixin_42160445/article/details/82348500

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值