JSR303(Bean Validation 1.0)
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是用于重新定义类上默认组的序列的组
- 类X声明的每个约束都没有声明组或显式声明组默认值,所有都是Default
由X实现的任何接口声明的每个约束,且未注释@GroupSequence不显式声明组或显式声明组默认值,X的接口上承载的所有默认约束被X继承。将忽略标记为@GroupSequence的接口
如果X有一个直接超类Y,则组Y中的每个约束,X的超类上承载的所有默认约束,由类层次结构继承
如果X没有@GroupSequence注释,则组默认值包含以下约束
此规则定义在验证X上的默认值时计算哪些约束
- 组X中的每个约束
- 如果X有一个直接超类Y,则Y中默认组的每个约束
如果Y重新定义组默认值,则此规则是必需的
如果X有@GroupSequence注释,则组默认值包含属于每个由@GroupSequence注释声明的组,@GroupSequence注释必须声明组X
对于每个接口Z,组Z包含以下约束
接口Z声明的每个约束,这些约束没有显式声明组或组默认值显式,位于接口Z上的所有默认约束:该规则正式定义了每个接口的隐式分组
由z的任何没有注释@GroupSequence的超级接口声明的每个约束(不显式声明组),Z的接口上承载的所有默认约束:组可以被继承
类X声明的每个约束,它显式声明了组Z,由X承载并标记了的每个约束属于组Z
由X实现的任何接口声明的每个约束,且未注释@GroupSequence显式声明组Z,由X承载并标记了的每个约束属于组Z
如果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)相关推荐
- JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践
任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用在很多时候,同样的数据验证逻辑会出现在不同的层, ...
- JSR303—Bean Validation验证
JSR-303 Bean Validation 是 JAVA EE 6 中的一项子规范 官方参考实现是Hibernate Validator 此实现与 Hibernate ORM 没有任何关系 Bea ...
- JSR-303 Bean Validation
JSR-303 Bean Validation https://www.jianshu.com/p/554533f88370 https://baijiahao.baidu.com/s?id=1667 ...
- JSR380(Bean Validation 2.0)
1.新的变化 支持验证容器元素 集合类型的级联验证. 支持java.util.Optional 支持JavaFX的属性类型 支持自定义容器类型 支持新的日期/时间类型 新的内置约束:@Email, @ ...
- Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
http://sishuok.com/forum/blogPost/list/7798.html 在之前的<跟我学SpringMVC>中的<第七章 注解式控制器的数据验证.类型转换及 ...
- 1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知
乔丹是我听过的篮球之神,科比是我亲眼见过的篮球之神.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免 ...
- Jakarta Bean Validation,Constrain once, validate everywhere!
前言 Jakarta Bean Validation到底是什么?我们不妨先看看其官网的相关介绍. Bean Validation 2.0 is a spec! It is done - after o ...
- @Valid 注解详解 Java Bean Validation的前世今生
Spring @Valid 注解 校验实体属性 1 @Valid 介绍 1.1 前言 1.2 Bean Validation 1.3 关于validation包 1.3 关于Spring Hibern ...
- Spring4 对Bean Validation规范的新支持(方法级别验证)
Bean Validation standardizes constraint definition, declaration and validation for the Java platform ...
最新文章
- 复旦 计算机 学硕 延毕,研究生招考呈现新趋势:非全日制招生遇冷 延期毕业现象越发明显...
- 【学习笔记】超简单的多项式求指(含泰勒展开式、牛顿迭代完成证明)
- git 提交命令_Git和Github快速上手指南
- HihoCoder - 1877 Approximate Matching(AC自动机+dp)
- 戴森吸尘器被《消费者报告》从推荐名单除名:不耐用
- Dart网络编程-备忘录2.0
- java base64字符 转图片_JAVA实现图片与base64字符串之间的转换详解
- imageview 自定义 android,Android自定义ImageView实现在图片上添加图层效果
- mcem r语言代码_生态学数据处理常用R语言代码
- ArcGIS多种面积计算方法的区别
- java存根_如何在JUnit和Java中使用存根?
- 赛扬n5095处理器怎么样 英特尔n5095核显相当于什么水平
- 今天写好汇报材料,明天升职加薪~
- html年龄0-120岁正则,正则表达式
- OA项目实战学习(3)——实现岗位管理增删改查
- 再见,2020。您好,2021!
- Windows程式开发设计指南--图形基础
- 关于嵌入式驱动开发,这篇文章让你了解透彻!
- 计算机中软键盘有哪些用途,电脑键盘的每个字母都有什么用途呢?
- pci-e服务器显卡性能,目前性能最好的显卡 NVIDIA发布Tesla V100,PCI-E接口
热门文章
- REPLICAT RORA_1保持 ABENDED状态,无法启动问题处理
- 9A0-054 Exam 专业认证
- ORACLE基础知识
- 没学过python、但是还是有公司要-学习python 基础都会了 为什么还是做不出项目呢?...
- python流程图基本元素-2-2:python之控制结构
- 开课吧python学费-安利一个特别棒的工具给大家
- python流程控制-Python 流程控制
- python笔记基础-Python基础教程学习笔记-1
- python中的装饰器有哪些-Python中的@函数装饰器到底是什么?
- python实现简单的api接口-对Python实现简单的API接口实例讲解