Bean Validation的1.0版本

1、约束定义

1.1 约束注解

Constraint 可用于字段、方法、属性、类型、注解类型,validatedBy返回的是ConstraintValidator类型的数组

@Documented
@Target({ ANNOTATION_TYPE })
@Retention(RUNTIME)
public @interface Constraint {
/**
* <code>ConstraintValidator</code> classes must reference distinct target types.
* If two <code>ConstraintValidator</code> refer to the same type,
* an exception will occur.
*
* @return array of ConstraintValidator classes implementing the constraint
*/
public Class<? extends ConstraintValidator<?, ?>>[] validatedBy();
}

约束的属性有三个基本的

String message() default '';
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};

1.2 应用相同类型的多个约束

使用常规注解,value返回元素类型为约束注解的数组,并且注解的保留策略必须是RUNTIME。@Target 建议与初始约束有相同。

建议约束注解与多值注解耦合在一起

1.3 约束组合

组合注解继承主约束注解的分组和payload

主注解如果想覆盖组合注解的属性,可以使用@OverridesAttribute或者@OverridesAttribute.List

@Retention(RUNTIME)
@Target({ METHOD })
public @interface OverridesAttribute {/*** @return Constraint type the attribute is overriding*/Class<? extends Annotation> constraint();/*** Name of the Constraint attribute overridden.* Defaults to the name of the attribute hosting <code>@OverridesAttribute</code>.** @return name of constraint attribute overridden.*/String name();/*** The index of the targeted constraint declaration when using* multiple constraints of the same type.* The index represents the index of the constraint in the value() array.** By default, no index is defined and the single constraint declaration* is targeted** @return constraint declaration index if multivalued annotation is used*/int constraintIndex() default -1;/*** Defines several @OverridesAttribute annotations on the same element* @see javax.validation.OverridesAttribute*/@Documented@Target({ METHOD })@Retention(RUNTIME)public @interface List {OverridesAttribute[] value();}
}

1.4 约束校验实现

通过注解@Contraint(validatedBy=<class>)指定

class需要实现ConstraintValidator泛型接口

T不能是参数化类型或者T的泛型参数必须是无界通配符

相关类图:

2、约束声明及校验处理

约束在类型上声明,评估实例或者实例图。

2.1 待验证类的要求

  • 属性需要遵循JavaBean读取属性的方法签名约定
  • 静态字段和方法不在校验范围内
  • 约束可以用于接口和超类

注解定义的目标可以是字段,属性或者类型,前提是:

  • 约束定义支持指定的目标类型(java.lang.annotation.Target)
  • 约束中声明的其中一个ConstraintValidator支持声明的目标类型

2.1.1 对象验证

约束声明用于类或者接口上。对类或接口应用约束表示对类或实现接口的类的状态的验证

2.1.2 字段和属性验证

约束声明可以应用于同一类型的字段和属性上。在字段和相关属性上同一约束不应该重复。推荐持有约束声明的对象绑定到单状态访问策略。

字段和方法的可见性不受约束。

2.1.3 图验证

图的结果验证作为一组统一的约束冲突返回。使用@Valid注解。

集合、数组、迭代器的字段和属性也可以用@Valid装饰。

2.2 约束声明

约束声明通过注解放在类或者接口上。约束注解可以应用于类型上、类型字段以及遵循JavaBean的属性上。

约束声明定义在类上,需要验证的类实例会传递给ConstraintValidator。

约束定义在字段上,字段值传递给ConstraintValidator

约束定义在getter方法上,getter方法的返回值传递给ConstraintValidator

2.3 继承(接口和超类)

约束声明放在接口上,对于给定类,约束声明放在超类上。

约束声明的影响是累加的。将验证在超类getter上声明的约束以及根据Java语言规范可见性规则在getter的重写版本上定义的任何约束

2.4 组和组序列

组定义约束子集。不是验证给定对象图的所有约束,只是验证其中的子集。子集通过目标组或者组群定义。每个约束声明定义所属的组列表。如果没有指定,属于Default组。

组由接口表示。

约束可以属于一个或者多个组。

2.4.1 组继承

在某些情况下,组是一个或者多个组的超集。组可以通过接口继承来继承一个或者多个组。

2.4.2 组序列

默认情况下,不管属于哪个组,约束检查没有固定的顺序。

通过注解@GroupSequence来指定次序。

组的组合不应该有环依赖。如果包含环依赖,验证计算时会抛出GroupDefinitionException异常。

定义了次序的组不应该直接继承其它组(即持有组序列的接口不应该有超接口)

定义了次序的组不应该直接用在约束声明中。

为了定义一个组为序列,接口必须用注解@GroupSequence标注

@Target({ TYPE })
@Retention(RUNTIME)
public @interface GroupSequence {Class<?>[] value();
}

2.4.3 为类重新定义默认组

重新定义类的默认组,在类上使用@GroupSequence注解。

定义在类A上的序列必须包含组A(在类上的默认注解必须是序列定义的一部分)。当@GroupSequence为类A定义Default组,但是不包含组A,当类验证时或者请求元数据是会抛出GroupDefinitionException异常。

2.4.4 隐式分组

接口Z上承载的每个约束以及默认组的一部分(隐式或显式)都属于组Z

2.4.5 正式组定义

对于每个类X

  • 对于X的每个超类Y,Y组包含Y的组Y的所有约束
  • 组X包含以下约束

组X是用于重新定义类上默认组的序列的组

  1. 类X声明的每个约束都没有声明组或显式声明组默认值,所有都是Default
  2. 由X实现的任何接口声明的每个约束,且未注释@GroupSequence不显式声明组或显式声明组默认值,X的接口上承载的所有默认约束被X继承。将忽略标记为@GroupSequence的接口

  3. 如果X有一个直接超类Y,则组Y中的每个约束,X的超类上承载的所有默认约束,由类层次结构继承

  • 如果X没有@GroupSequence注释,则组默认值包含以下约束

此规则定义在验证X上的默认值时计算哪些约束

  1. 组X中的每个约束
  2. 如果X有一个直接超类Y,则Y中默认组的每个约束

如果Y重新定义组默认值,则此规则是必需的

  • 如果X有@GroupSequence注释,则组默认值包含属于每个由@GroupSequence注释声明的组,@GroupSequence注释必须声明组X

  • 对于每个接口Z,组Z包含以下约束

  1. 接口Z声明的每个约束,这些约束没有显式声明组或组默认值显式,位于接口Z上的所有默认约束:该规则正式定义了每个接口的隐式分组

  2. 由z的任何没有注释@GroupSequence的超级接口声明的每个约束(不显式声明组),Z的接口上承载的所有默认约束:组可以被继承

  3. 类X声明的每个约束,它显式声明了组Z,由X承载并标记了的每个约束属于组Z

  4. 由X实现的任何接口声明的每个约束,且未注释@GroupSequence显式声明组Z,由X承载并标记了的每个约束属于组Z

  5. 如果X有一个直接超类Y,则Y的Z组中的每个约束,由X的任何超类承载并标记了的每个约束为属于组Z

  • 对于每个注解了@GroupSequence的接口z,组z包含了属于注解@GroupSequence声明的每个组的每个约束。

2.5 验证过程

验证指定组,应用于指定bean实例的验证过程会执行如下的约束验证:

  • 所有可到达的字段,执行符合组的字段级别的验证
  • 所有可到达的getter要,执行所有指定符合组的getter级别的验证。
  • 执行所有匹配目标组的类级别的验证。
  • 对于所有可到达的以及级联的关系,执行所有级联的验证。

2.5.1 可遍历的属性

3、Validation API

4、元数据请求API

5、内置约束定义

@Null
@NotNull
@AssertTrue
@AssertFalse
@Min
@Max
@DecimalMin
@DecimalMax
@Size
@Digits
@Past
@Future
@Pattern

参考资料:

https://beanvalidation.org/

JSR303(Bean Validation 1.0)相关推荐

  1. JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践

    任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用在很多时候,同样的数据验证逻辑会出现在不同的层, ...

  2. JSR303—Bean Validation验证

    JSR-303 Bean Validation 是 JAVA EE 6 中的一项子规范 官方参考实现是Hibernate Validator 此实现与 Hibernate ORM 没有任何关系 Bea ...

  3. JSR-303 Bean Validation

    JSR-303 Bean Validation https://www.jianshu.com/p/554533f88370 https://baijiahao.baidu.com/s?id=1667 ...

  4. JSR380(Bean Validation 2.0)

    1.新的变化 支持验证容器元素 集合类型的级联验证. 支持java.util.Optional 支持JavaFX的属性类型 支持自定义容器类型 支持新的日期/时间类型 新的内置约束:@Email, @ ...

  5. Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC

    http://sishuok.com/forum/blogPost/list/7798.html 在之前的<跟我学SpringMVC>中的<第七章 注解式控制器的数据验证.类型转换及 ...

  6. 1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知

    乔丹是我听过的篮球之神,科比是我亲眼见过的篮球之神.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免 ...

  7. Jakarta Bean Validation,Constrain once, validate everywhere!

    前言 Jakarta Bean Validation到底是什么?我们不妨先看看其官网的相关介绍. Bean Validation 2.0 is a spec! It is done - after o ...

  8. @Valid 注解详解 Java Bean Validation的前世今生

    Spring @Valid 注解 校验实体属性 1 @Valid 介绍 1.1 前言 1.2 Bean Validation 1.3 关于validation包 1.3 关于Spring Hibern ...

  9. Spring4 对Bean Validation规范的新支持(方法级别验证)

    Bean Validation standardizes constraint definition, declaration and validation for the Java platform ...

最新文章

  1. 复旦 计算机 学硕 延毕,研究生招考呈现新趋势:非全日制招生遇冷 延期毕业现象越发明显...
  2. 【学习笔记】超简单的多项式求指(含泰勒展开式、牛顿迭代完成证明)
  3. git 提交命令_Git和Github快速上手指南
  4. HihoCoder - 1877 Approximate Matching(AC自动机+dp)
  5. 戴森吸尘器被《消费者报告》从推荐名单除名:不耐用
  6. Dart网络编程-备忘录2.0
  7. java base64字符 转图片_JAVA实现图片与base64字符串之间的转换详解
  8. imageview 自定义 android,Android自定义ImageView实现在图片上添加图层效果
  9. mcem r语言代码_生态学数据处理常用R语言代码
  10. ArcGIS多种面积计算方法的区别
  11. java存根_如何在JUnit和Java中使用存根?
  12. 赛扬n5095处理器怎么样 英特尔n5095核显相当于什么水平
  13. 今天写好汇报材料,明天升职加薪~
  14. html年龄0-120岁正则,正则表达式
  15. OA项目实战学习(3)——实现岗位管理增删改查
  16. 再见,2020。您好,2021!
  17. Windows程式开发设计指南--图形基础
  18. 关于嵌入式驱动开发,这篇文章让你了解透彻!
  19. 计算机中软键盘有哪些用途,电脑键盘的每个字母都有什么用途呢?
  20. pci-e服务器显卡性能,目前性能最好的显卡 NVIDIA发布Tesla V100,PCI-E接口

热门文章

  1. REPLICAT RORA_1保持 ABENDED状态,无法启动问题处理
  2. 9A0-054 Exam 专业认证
  3. ORACLE基础知识
  4. 没学过python、但是还是有公司要-学习python 基础都会了 为什么还是做不出项目呢?...
  5. python流程图基本元素-2-2:python之控制结构
  6. 开课吧python学费-安利一个特别棒的工具给大家
  7. python流程控制-Python 流程控制
  8. python笔记基础-Python基础教程学习笔记-1
  9. python中的装饰器有哪些-Python中的@函数装饰器到底是什么?
  10. python实现简单的api接口-对Python实现简单的API接口实例讲解