• Unreal is funny !!!

Spring项目中Bean的校验 javax.validation

Java 站长 5年前 (2020-04-22) 1203次浏览 已收录 0个评论
文章目录[隐藏]

在java项目中,我们经常需要对java对象的格式进行验证,比如接口传进来的User对象的name不能为空,我们传出去的数据的数据要符合规范,传出去前先手动验证, 如果用代码一个一个判断,那可太low了,幸好Spring项目中含有相应的工具。

手动验证

怎么判断一个对象是否符合注解说明的格式?上代码

场景:一个学生有个书包,学生和书包的名字都不能为空

 

@Data
public class Student {

    @NotBlank(message = "学生名字不能为空")
    private String name;

    @NotNull
    @Min(0)
    private Integer age;

    @Valid
    @NotNull
    private Bag bag;

}

@Data
public class Bag {

    private Integer weight;

    @NotBlank(message = "书包名字不能为空")
    private String name;

}

private static Validator validator = Validation.buildDefaultValidatorFactory()
            .getValidator();

    public static void main(String[] args) {
        Bag bag = new Bag();
        bag.setName("");
        bag.setWeight(343);

        Student student = new Student();
        student.setAge(343);
        student.setName("fdsfs");

        student.setBag(bag);

        Set<ConstraintViolation> set = validator.validate(student, Default.class);
        if (set != null && set.size() > 0) {
            for (ConstraintViolation cv : set) {
                System.out.println("====");
                System.out.println(cv);
            }
        }
    }

当需要对嵌套的对象也进行验证的时候,需要在被嵌套的属性上加上 @Valid注解 ,默认如果嵌套的属性为null,那就不验证它了,如果你想验证它不为null,加@NotNull注解。

spring 框架中使用的 Validator

spring 框架中也有同样的代码,主要有两块:
1,添加到注入的Component里面,spring 初始化容器对象的时候会进行验证,
org/springframework/validation/beanvalidation/BeanValidationPostProcessor.java

 

@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (this.afterInitialization) {
			doValidate(bean);
		}
		return bean;
	}


	/**
	 * Perform validation of the given bean.
	 * @param bean the bean instance to validate
	 * @see javax.validation.Validator#validate
	 */
	protected void doValidate(Object bean) {
		Assert.state(this.validator != null, "No Validator set");
		Set<ConstraintViolation<Object>> result = this.validator.validate(bean);
		if (!result.isEmpty()) {
			StringBuilder sb = new StringBuilder("Bean state is invalid: ");
			for (Iterator<ConstraintViolation<Object>> it = result.iterator(); it.hasNext();) {
				ConstraintViolation<Object> violation = it.next();
				sb.append(violation.getPropertyPath()).append(" - ").append(violation.getMessage());
				if (it.hasNext()) {
					sb.append("; ");
				}
			}
			throw new BeanInitializationException(sb.toString());
		}
	}

这个BeanPostProcessor就是在每个bean被创建的时候,属性设置完成后,拦截一下,验证一下这个bean的属性符不符合注解的要求,不符合就扔异常

2,controller,service方法参数里面,对参数验证
org/springframework/validation/beanvalidation/MethodValidationInterceptor.java

@Override
	@SuppressWarnings("unchecked")
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Class<?>[] groups = determineValidationGroups(invocation);

		// Standard Bean Validation 1.1 API
		ExecutableValidator execVal = this.validator.forExecutables();
		Method methodToValidate = invocation.getMethod();
		Set<ConstraintViolation<Object>> result;

		try {
			result = execVal.validateParameters(
					invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
		}
		catch (IllegalArgumentException ex) {
			// Probably a generic type mismatch between interface and impl as reported in SPR-12237 / HV-1011
			// Let's try to find the bridged method on the implementation class...
			methodToValidate = BridgeMethodResolver.findBridgedMethod(
					ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass()));
			result = execVal.validateParameters(
					invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
		}
		if (!result.isEmpty()) {
			throw new ConstraintViolationException(result);
		}

		Object returnValue = invocation.proceed();

		result = execVal.validateReturnValue(invocation.getThis(), methodToValidate, returnValue, groups);
		if (!result.isEmpty()) {
			throw new ConstraintViolationException(result);
		}

		return returnValue;
	}

这个拦截的是被 @Validated注解的类上的方法,对方法的入参进行一个拦截,
当然第二个其实我不是看的懂,以后更新。


本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Spring项目中Bean的校验 javax.validation
喜欢 (5)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址