目录
.结论先出
ValidVSValidatd相同点
JSR80
ValidVSValidatd不同点?
Valid和
Validatd区别Validator
.
Valid和Validatd注解.例子
4.使用
Valid嵌套校验5.组合使用
Valid和Validatd进行集合校验6.自定义校验
空与非空检查
Boolan值检查
日期检查
数值检查
其他
hibrnat-validator扩展约束(部分)
自定义约束注解
工作原理
结论
.结论先出
ValidVSValidatd相同点
都可以对方法和参数进行校验
Valid和Validatd两种注释都会导致应用标准Ban验证。
如果验证不通过会抛出BindExcption异常,并变成(BAD_REQUEST)响应;或者可以通过Errors或BindingRsult参数在控制器内本地处理验证错误。另外,如果参数前有
RqustBody注解,验证错误会抛出MthodArgumntNotValidExcption异常。JSR80
JSR80是用于ban验证的JavaAPI规范,是JakartaEE和JavaSE的一部分。这确保ban的属性满足特定条件,使用诸如
NotNull、Min和Max之类的注释。此版本需要Java8或更高版本,并利用Java8中添加的新功能,例如类型注释和对Optional和LocalDat等新类型的支持。
有关规范的完整信息,请继续阅读JSR80。
ValidVSValidatd不同点?
javax.validation.Valid是JSR-0规范标准注解支持,是一个标记注解。注解支持ElmntTyp#METHOD,ElmntTyp#FIELD,ElmntTyp#CONSTRUCTOR,ElmntTyp#PARAMETER,ElmntTyp#TYPE_USEorg.springframwork.validation.annotation.Validatd是Spring做得一个自定义注解,增强了分组功能。注解支持ElmntTyp#TYPE,ElmntTyp#METHOD,ElmntTyp#PARAMETER
Valid和Validatd区别Validator
BanValidation.0(JSR80)定义了用于实体和方法验证的元数据模型和API,HibrnatValidator是目前最好的实现
Validator接口有三个方法,可用于验证整个实体或仅验证实体的单个属性
Validator#validat()验证所有ban的所有约束Validator#validatProprty()验证单个属性Validator#validatValu()检查给定类的单个属性是否可以成功验证
不管是qustBody参数校验还是方法级别的校验,最终都是调用HibrnatValidator执行校验,SpringValidation只是做了一层封装。
验证用户的输入是我们大多数应用程序中的常见功能。在Java生态系统中,我们专门使用JavaStandardBanValidationAPI来支持这一点。此外,从4.0版本开始,这也与Spring很好地集成在一起.
在接下来的部分中,让我们详细了解它们。
.
Valid和Validatd注解在Spring中,我们使用JSR-0的
Valid注释进行方法级别验证。此外,我们还使用它来标记成员属性以进行验证。但是,此注释不支持组验证。组有助于限制验证期间应用的约束。一个特殊的用例是UI界面(UIwizards)。在这里,在第一步中,我们可能有某个字段子组。在后续步骤中,可能有另一个组属于同一个ban。因此我们需要在每一步中对这些有限的字段应用约束,但
Valid不支持这一点。在这种情况下,对于组级别,我们必须使用Spring的
Validatd,它是JSR-0的Valid的变体。这是在方法级别使用的。对于标记成员属性,我们继续使用Valid注释。现在,让我们直接进入并通过一个例子来看看这些注解的用法。
.例子
让我们考虑一个使用SpringBoot开发的简单用户注册。首先,我们将只有名称和密码属性:
publicclassUsrAccount{
NotNullSiz(min=4,max=5)privatStringpassword;NotBlankprivatStringnam;//standardconstructors/sttrs/gttrs/toString}接下来,让我们看看控制器。在这里,我们将使用带有
Valid注释的savBasicInfo方法来验证用户输入:RqustMapping(valu="/savBasicInfo",mthod=RqustMthod.POST)publicStringsavBasicInfo(
ValidModlAttribut("usraccount")UsrAccountusraccount,BindingRsultsult,ModlMapmodl){if(sult.hasErrors()){turn"rror";}turn"succss";}现在让我们测试这个方法:
TstpublicvoidgivnSavBasicInfo_whnCorctInput_thnSuccss()throwsExcption{this.mockMvc.prform(MockMvcRqustBuildrs.post("/savBasicInfo").accpt(MdiaTyp.TEXT_HTML).param("nam","tst").param("password","pass")).andExpct(viw().nam("succss")).andExpct(status().isOk()).andDo(print());}
确认测试运行成功后,我们现在扩展功能。下一个合乎逻辑的步骤是将其转换为复杂用户注册。第一步,名称和密码保持不变。在第二步中,我们将获取诸如年龄和电话之类的附加信息。因此,我们将使用这些附加字段更新我们的域对象:
publicclassUsrAccount{
NotNullSiz(min=4,max=5)privatStringpassword;NotBlankprivatStringnam;Min(valu=8,mssag="Agshouldnotblssthan8")privatintag;NotBlankprivatStringphon;//standardconstructors/sttrs/gttrs/toString}但是,这一次我们会注意到之前的测试失败了。这是因为我们没有传入ag和phon字段。为了支持这种行为,我们需要组验证和
Validatd注释。为此,我们需要对字段进行分组,创建两个不同的组。首先,我们需要创建两个标记接口。每个组或每个步骤单独一个。我们可以参考我们关于组验证的文章以了解具体的实现方式。在这里,让我们