java bean 属性验证框架 valid.docx
- 文档编号:7211991
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:25
- 大小:27.26KB
java bean 属性验证框架 valid.docx
《java bean 属性验证框架 valid.docx》由会员分享,可在线阅读,更多相关《java bean 属性验证框架 valid.docx(25页珍藏版)》请在冰豆网上搜索。
javabean属性验证框架valid
项目介绍
java开发中,参数校验是非常常见的需求。
但是hibernate-validator在使用过程中,依然会存在一些问题。
特性
•支持fluent-validation
•支持jsr-303注解
•支持i18n
•支持用户自定义策略
•支持用户自定义注解
开源地址
valid
创作目的
hibernate-validator无法满足的场景
如今java最流行的hibernate-validator框架,但是有些场景是无法满足的。
比如:
1.验证新密码和确认密码是否相同。
(同一对象下的不同属性之间关系)
2.当一个属性值满足某个条件时,才进行其他值的参数校验。
3.多个属性值,至少有一个不能为null
其实,在对于多个字段的关联关系处理时,hibernate-validator就会比较弱。
本项目结合原有的优点,进行这一点的功能强化。
validation-api过于复杂
validation-api提供了丰富的特性定义,也同时带来了一个问题。
实现起来,特别复杂。
然而我们实际使用中,常常不需要这么复杂的实现。
valid-api提供了一套简化很多的api,便于用户自行实现。
自定义缺乏灵活性
hibernate-validator在使用中,自定义约束实现是基于注解的,针对单个属性校验不够灵活。
本项目中,将属性校验约束和注解约束区分开,便于复用和拓展。
过程式编程vs注解式编程
hibernate-validator核心支持的是注解式编程,基于bean的校验。
一个问题是针对属性校验不灵活,有时候针对bean的校验,还是要自己写判断。
本项目支持fluent-api进行过程式编程,同时支持注解式编程。
尽可能兼顾灵活性与便利性。
项目模块说明
模块名称
说明
valid-api
核心api及注解定义
valid-core
针对valid-api的核心实现
valid-jsr
针对JSR-303标准注解的实现
valid-test
测试代码模块
依赖说明
valid-core默认引入valid-api
valid-jsr默认引入valid-core
快速开始
准备工作
JDK1.7+
Maven3.X+
maven引入
例子
我们直接利用jsr内置的约束类:
publicvoidhelloValidTest(){
IResultresult=ValidBs.on(null,JsrConstraints.notNullConstraint())
.result()
.print();
Assert.assertFalse(result.pass());
}
对应日志输出为:
DefaultResult{pass=false,notPassList=[DefaultConstraintResult{pass=false,message='预期值为
方法初步说明
ValidBs用来进行验证的引导类,上述的写法等价于如下:
publicvoidhelloValidAllConfigTest(){
IResultresult=ValidBs.on(null,JsrConstraints.notNullConstraint())
.fail(Fails.failFast())
.group()
.valid(DefaultValidator.getInstance())
.result()
.print();
Assert.assertFalse(result.pass());
}
on(Objectvalue,IConstraint…constraints)指定约束
Object可以是对象,也可以是普通的值。
constraints为对应的约束列表,为默认的约束验证提供便利性。
IConstraint相关创建工具类Constraints、JsrConstraints
fail(IFailfail)
可以指定失败时的处理策略,支持用户自定义失败策略。
实现
说明
failOver
失败后继续验证,直到验证完所有属性
failFast
失败后快速返回
group(Class[]classes)支持分组验证
有时候我们希望,只验证指定某一分组的约束。
可以通过group()属性指定,与IConstraint中的group()属性匹配的约束才会被执行。
valid(IValidatorvalidator)支持验证策略
默认为DefaultValidator,为valid-api的实现验证。
如果你希望使用jsr-303注解,可以使用JsrValidator。
支持自定义验证策略。
result(IResultHandlerresultHandler)验证结果处理
默认为simple()的简单结果处理。
可以指定为detail()进行详细结果处理查看。
支持用户自定义结果处理策略。
IResult内置方法
simple()/detail()处理的结果为IResult实现类。
IResult支持如下方法:
•print()
对结果进行打印,主要便于调试。
•throwEx()
对于参数的校验,一般都是基于异常结合springaop来处理的。
throwsEx会在验证不通过时,抛出ValidRuntimeException异常,对应message为提示消息。
@Test(expected=ValidRuntimeException.class)
publicvoidresultThrowsExTest(){
ValidBs.on(null,notNullValidatorEntry())
.valid()
.result()
.throwsEx();
}
内置的属性约束
上面我们对ValidBs有了一个整体的了解,下面来看一看系统内置的属性约束有哪些。
每个属性约束都有对应注解。
针对单个属性,直接使用属性约束即可,灵活快捷。
针对bean校验,可以结合注解实现,类似于hibernate-validator。
valid-core
核心内置属性约束实现。
enumRangesConstraint
枚举类指定范围约束
•创建方式
参见工具类Constraints#enumRangesConstraint
/**
*枚举范围内约束
*
(1)当前值必须在枚举类对应枚举的toString()列表中。
*@paramenumClass枚举类,不可为空
*@return约束类
*@since0.1.1
*@seecom.github.houbb.valid.core.annotation.constraint.EnumRanges枚举类指定范围注解
*/
publicstaticIConstraintenumRangesConstraint(finalClass
extendsEnum>enumClass)
•测试案例
参见测试类EnumsRangesConstraintTest
IResultresult=ValidBs.on("DEFINE",Constraints.enumRangesConstraint(FailTypeEnum.class))
.result();
Assert.assertFalse(result.pass());
•说明
FailTypeEnum是valid-api内置的枚举类,枚举值为FAIL_FAST/FAIL_OVER。
只有属性值在枚举值范围内,验证才会通过。
rangesConstraint
指定属性范围内约束
•创建方式
参见工具类Constraints#rangesConstraint
*值在指定范围内约束
*
(1)这里为了和注解保持一致性,暂时只支持String
*@paramstrings对象范围
*@return约束类
*@since0.1.1
*@seecom.github.houbb.valid.core.annotation.constraint.RangesString指定范围内注解
*/
publicstaticIConstraintrangesConstraint(String...strings)
•测试案例
参见测试类RangesConstraintTest
IResultresult=ValidBs.on("DEFINE",Constraints.rangesConstraint("FAIL_OVER",
"FAIL_FAST"))
.result();
Assert.assertFalse(result.pass());
•说明
这个相对于枚举值,更加灵活一些。
可以根据自己的需要,指定属性的范围。
valid-jsr
valid-jsr中内置注解,和jsr-303标准一一对应,此处不再赘述。
创建方式见工具类JsrConstraints,测试代码见xxxConstraintTest。
对应列表如下:
属性约束
注解
简介
AssertFalseConstraint
@AssertFalse
指定值必须为false
AssertTrueConstraint
@AssertTrue
指定值必须为true
MinConstraint
@Min
指定值必须大于等于最小值
MaxConstraint
@Max
指定值必须小于等于最大值
DecimalMinConstraint
@DecimalMin
指定金额必须大于等于最小值
DecimalMaxConstraint
@DecimalMax
指定金额必须小于等于最大值
DigitsConstraint
@Digits
指定值位数必须符合要求
FutureConstraint
@Future
指定日期必须在未来
PastConstraint
@Past
指定日期必须在过去
PatternConstraint
@Pattern
指定值必须满足正则表达式
SizeConstraint
@Size
指定值必须在指定大小内
自定义约束实现
需求
实际业务需求的是不断变化的,内置的属性约束常常无法满足我们的实际需求。
我们可以通过自定义属性,来实现自己的需求。
例子
参见类DefineConstraintTest
自定义notNullConstraint
notNullConstraint对于null值是严格的。
所以继承自AbstractStrictConstraint,如下:
IResultresult=ValidBs.on(null,newAbstractStrictConstraint(){
@Override
protectedbooleanpass(IConstraintContextcontext,Objectvalue){
returnvalue!
=null;
}
}).result();
Assert.assertFalse(result.pass());
自定义assertTrueConstraint
在jsr-303标准中,除却@NotNull对于null值都是非严格校验的。
继承自AbstractConstraint即可,如下:
IConstraintassertTrueConstraint=newAbstractConstraint
@Override
protectedbooleanpass(IConstraintContextcontext,Booleanvalue){
returnfalse;
}
};
IResultnullValid=ValidBs.on(null,assertTrueConstraint)
.result();
Assert.assertTrue(nullValid.pass());
IResultfalseValid=ValidBs.on(false,assertTrueConstraint)
.result();
Assert.assertFalse(falseValid.pass());
core模块注解验证
内置注解
注解
说明
@AllEquals
当前字段及指定字段值必须全部相等
@HasNotNull
当前字段及指定字段值至少有一个不为null
@EnumRanges
当前字段值必须在枚举属性范围内
@Ranges
当前字段值必须在指定属性范围内
测试对象
•User.java
publicclassUser{
/**
*名称
*/
@HasNotNull({"nickName"})
privateStringname;
/**
*昵称
*/
privateStringnickName;
/**
*原始密码
*/
@AllEquals("password2")
privateStringpassword;
/**
*新密码
*/
privateStringpassword2;
/**
*性别
*/
@Ranges({"boy","girl"})
privateStringsex;
/**
*失败类型枚举
*/
@EnumRanges(FailTypeEnum.class)
privateStringfailType;
//fluentgetter&setter
}
我们限制name/nickName至少有一个不为空,password/password2值要一致。
以及限定了sex的范围值和failType的枚举值。
测试代码
Useruser=newUser();
user.sex("what").password("old").password2("new")
.failType("DEFINE");
IResultresult=ValidBs.on(user)
.fail(Fails.failOver())
.result()
.print();
Assert.assertFalse(result.pass());
•日志
DefaultResult{pass=false,notPassList=[DefaultConstraintResult{pass=false,message='值
jsr模块注解验证
注解
与jsr-303注解标准保持一致。
对象定义
为了演示,简单定义如下:
•JsrUser.java
publicclassJsrUser{
@Null
privateObjectnullVal;
@NotNull
privateStringnotNullVal;
@AssertFalse
privatebooleanassertFalse;
@AssertTrue
privatebooleanassertTrue;
@Pattern(regexp="[123456]{2}")
privateStringpattern;
@Size(min=2,max=5)
privateStringsize;
@DecimalMax("12.22")
privateBigDecimaldecimalMax;
@DecimalMin("1.22")
privateBigDecimaldecimalMin;
@Min(10)
privatelongmin;
@Max(10)
privatelongmax;
@Past
privateDatepast;
@Future
privateDatefuture;
@Digits(integer=2,fraction=4)
privateLongdigits;
//fluentgetterandsetter
}
测试代码
参见测试类ValidBsJsrBeanTest
publicvoidbeanFailTest(){
Datefuture=DateUtil.getFormatDate("90190101",DateUtil.PURE_DATE_FORMAT);
Datepast=DateUtil.getFormatDate("20190101",DateUtil.PURE_DATE_FORMAT);
JsrUserjsrUser=newJsrUser();
jsrUser.assertFalse(true)
.assertTrue(false)
.decimalMin(newBigDecimal("1"))
.decimalMax(newBigDecimal("55.55"))
.min(5)
.max(20)
.digits(333333L)
.future(past)
.past(future)
.nullVal("123")
.notNullVal(null)
.pattern("asdfasdf")
.size("22222222222222222222");
IResultresult=ValidBs.on(jsrUser)
.fail(Fails.failOver())
.valid(JsrValidator.getInstance())
.result()
.print();
Assert.assertFalse(result.pass());
}
•日志
DefaultResult{pass=false,notPassList=[DefaultConstraintResult{pass=false,message='值必须为空',value=123,constraint='NullConstraint',expectValue='null'},DefaultConstraintResult{pass=false,message='值必须为非空',value=null,constraint='NotNullConstraint',expectValue='notnull'},DefaultConstraintResult{pass=false,message='值必须为假',value=true,constraint='AssertFalseConstraint',expectValue='false'},DefaultConstraintResult{pass=false,message='值必须为真',value=false,constraint='AssertTrueConstraint',expectValue='true'},DefaultConstraintResult{pass=false,message='值必须满足正则表达式',value=asdfasdf,constraint='PatternConstraint',expectValue='必须匹配正则表达式[123456]{2}'},DefaultConstraintResult{pass=false,message='值必须为在指定范围内',value=22222222222222222222,constraint='SizeConstraint',expectValue='大小必须在范围内[2,5]'},DefaultConstraintResult{pass=false,message='值必须小于金额最大值',value=55.55,constraint='DecimalMaxConstraint',expectValue='小于等于12.22'},DefaultConstraintResult{pass=false,message='值必须大于金额最小值',value=1,constraint='DecimalMinConstraint',expectValue='大于等于1.22'},DefaultConstraintResult{pass=false,message='值必须大于最小值',value=5,constraint='MinConstraint',expectValue='大于等于10'},DefaultConstraintResult{pass=false,message='值必须小于最大值',value=20,constraint='MaxConstraint',expectValue='小于等于10'},DefaultConstraintResult{pass=false,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java bean 属性验证框架 valid 属性 验证 框架