Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

🚥Fluent-validation framework for java extend from hibernate-validator.(java 对象属性流式验证框架,下一代校验框架。兼容实现 jakarta bean validation、jsr 303、hibernate-validator)

License

NotificationsYou must be signed in to change notification settings

houbb/validator

Repository files navigation

java 开发中,参数校验是非常常见的需求。但是 hibernate-validator 在使用过程中,依然会存在一些问题。

validator 在 hibernate-validator 等校验工具之上,做了一些改进,使其使用更加便捷优雅,进一步提升工作效率。

Maven CentralOpen Source LoveBuild StatusCoverage Status

变更日志

变更日志

特性

  • 兼容实现 jakarta bean validation(jsr-303)内置注解

  • 兼容实现 hibernate-validation

  • 支持 i18n

  • 支持用户自定义策略

  • 支持用户自定义注解

  • 支持针对属性的校验

  • 支持过程式编程与注解式编程

  • 支持指定校验生效的条件

创作目的

hibernate-validator 无法满足的场景

如今 java 最流行的 hibernate-validator 框架,但是有些场景是无法满足的。

比如:

  1. 验证新密码和确认密码是否相同。(同一对象下的不同属性之间关系)

  2. 当一个属性值满足某个条件时,才进行其他值的参数校验。

  3. 多个属性值,至少有一个不能为 null

其实,在对于多个字段的关联关系处理时,hibernate-validator 就会比较弱

本项目结合原有的优点,进行这一点的功能强化。

validation-api 过于复杂

validation-api 提供了丰富的特性定义,也同时带来了一个问题。

实现起来,特别复杂。

然而我们实际使用中,常常不需要这么复杂的实现。

validator-api 提供了一套简化很多的 api,便于用户自行实现。

自定义缺乏灵活性

hibernate-validator 在使用中,自定义约束实现是基于注解的,针对单个属性校验不够灵活。

本项目中,将属性校验约束和注解约束区分开,便于复用和拓展

过程式编程 vs 注解式编程

hibernate-validator 核心支持的是注解式编程,基于 bean 的校验。

一个问题是针对属性校验不灵活,有时候针对 bean 的校验,还是要自己写判断。

本项目支持 fluent-api 进行过程式编程,同时支持注解式编程。

尽可能兼顾灵活性与便利性。

快速开始

准备工作

JDK1.7+

Maven 3.X+

maven 引入

<dependency>    <groupId>com.github.houbb</groupId>    <artifactId>validator-core</artifactId>    <version>0.7.0</version></dependency>

快速入门

定义对象

第一步,我们定义一个常见的 java bean 对象,可以指定内置的注解。

支持 jsr-303 注解和 hibernate-validator 的注解。

publicclassUser {/**     * 名称     */@HasNotNull({"nickName"})privateStringname;/**     * 昵称     */privateStringnickName;/**     * 原始密码     */@AllEquals("password2")privateStringpassword;/**     * 新密码     */privateStringpassword2;/**     * 性别     */@Ranges({"boy","girl"})privateStringsex;/**     * 失败类型枚举     */@EnumRanges(FailTypeEnum.class)privateStringfailType;//getter & setter}

ValidHelper 工具方法

ValidHelper 作为统一封装的工具类,提供了 java bean 校验常见的方法。

方法列表:

序号方法返回值说明
1failOver(Object object)IResult全部验证后返回
2failFast(Object object)IResult快速验证后返回
3failOverThrow(Object object)void全部验证后返回-未通过抛出异常
4failFastThrow(Object object)void快速验证后返回-未通过抛出异常
5failOver(Object object, IConstraint Constraint)IResult全部验证后返回,属性校验
6failFast(Object object, IConstraint Constraint)IResult快速验证后返回,属性校验
7failOverThrow(Object object, IConstraint Constraint)void全部验证后返回-未通过抛出异常,属性校验
8failFastThrow(Object object, IConstraint Constraint)void快速验证后返回-未通过抛出异常,属性校验
9failOver(Object object, IConstraint Constraint, String message)IResult全部验证后返回,属性校验,message 为报错信息
10failFast(Object object, IConstraint Constraint, String message)IResult快速验证后返回,属性校验,message 为报错信息
11failOverThrow(Object object, IConstraint Constraint, String message)void全部验证后返回-未通过抛出异常,属性校验,message 为报错信息
12failFastThrow(Object object, IConstraint Constraint, String message)void快速验证后返回-未通过抛出异常,属性校验,message 为报错信息

使用起来很简单,我们以 failFast 为例:

// 对象定义Useruser =newUser();user.sex("what").password("old").password2("new");// 调用方法IResultresult =ValidHelper.failFast(user);

结果:

DefaultResult{pass=false, notPassList=[DefaultConstraintResult{pass=false, message='name: 值 <null> 不是预期值', value=null, constraint='HasNotNullConstraint', expectValue='', fieldName='name'}], allList=null}
  • IResult 方法说明

返回值实现默认为 DefaultResult,接口 IResult 属性如下:

publicinterfaceIResult {/**     * 是否全部通过验证     * @return 是否     * @since 0.1.0     */booleanpass();/**     * 未通过的列表信息     * @return 验证结果     * @since 0.1.0     */List<IConstraintResult>notPassList();/**     * 所有的验证结果列表     * @return 所有的验证结果     * @since 0.1.0     */List<IConstraintResult>allList();/**     * 输出信息到控台     * (1)主要是为了方便调整     * (2)该功能其实可以做增强,比如输出到文件/数据库等等。     * @return this     * @since 0.0.6     */IResultprint();/**     * 对于未通过的信息,     * (1)未通过的界定。     *  {@link IConstraintResult#pass()} 为 false     *     * (2)内容信息     * 抛出运行时异常 {@link com.github.houbb.validator.api.exception.ValidRuntimeException},异常信息为 {@link IConstraintResult#message()} 消息     * (3)内容限定     *  为了避免异常内容过多,只抛出第一条即可。     *  (4)改方法的增强空间     *  4.1 可以指定什么情况下抛出异常     *  4.2 抛出异常的信息和类别     *     * @return this     * @since 0.0.6     */IResultthrowsEx();}

注解说明

java bean 的校验,基于注解是比较方便的。和 hibernate-validator 使用类似,这里介绍下常见的注解。

内置约束注解

内置注解如下:

序号注解value()说明
1@AllEqualsString[]当前字段及其指定的字段 全部相等
2@EnumRangesClass<? extends Enum>当前字段必须在枚举值指定的范围内
3@HasNotNullString[]当前字段及其指定的字段 至少有一个不为 null
4@RangesString[]当前字段必须在指定的范围内
4@RangesString[]当前字段必须在指定的范围内
5@ChinaPhone中国手机号校验
6@ChinaIdNo中国身份证校验

JSR-303 / jakarta bean validation 约束注解支持

jakarta-bean-validation-spec-3.0

序号注解说明
1@AssertTrue为 true 约束条件
2@AssertFalse为 false 约束条件
3@Null为 null 约束条件
4@NotNull不为 null 约束条件
5@Past是否在当前时间之前约束条件
6@PastOrPresent是否在当前时间之前约束条件,包含当前
7@Future是否在当前时间之后约束条件
8@FutureOrPresent是否在当前时间之后约束条件,包含当前
9@Pattern正则表达式约束条件
10@Size在指定范围内的约束条件
11@Digits数字位数的约束条件
12@DecimalMax最大数字的约束条件
13@DecimalMin最小数字的约束条件
14@Min最小的约束条件
15@Max最大的约束条件
16@NotBlank不能为空格的约束条件
17@NotEmpty不能为空的约束条件
18@EmailEmail 约束条件
19@Negative指定值必须为负数约束条件
20@NegativeOrZero指定值必须为负数约束条件,包含0
21@Positive指定值必须为正数约束条件
22@PositiveOrZero指定值必须为正数约束条件,包含0

hibernate-validator 约束注解支持

hibernate-validator 内置注解

实现了常见的几个,后续将陆续完善:

序号注解说明
1@NotBlank不能为空格的约束条件
2@NotEmpty不能为空的约束条件
3@Length长度的约束条件
4@URLURL 约束条件
5@EmailEmail 约束条件
6@UniqueElements元素唯一约束条件
7@Range指定范围元素约束条件

条件注解

说明

有时候我们需要根据不同的参数,进行不同的限制条件。

比如新建时用户 id 不需要传入,但是修改时 id 必填。

如果是传统的 hibernate-validator 处理就会比较麻烦,此处引入条件注解。

内置注解

序号注解说明
1@EqualsCondition等于指定值的条件
2@NotEqualsCondition不等于指定值的条件
3@AlwaysTrueCondition永远生效的条件
4@AlwaysFalseCondition永远不生效的条件

使用

使用起来也不难,下面的效果如下:

  1. operType == 'create' 时,name 的校验才会生效。
  2. operType != 'create' 时,id 的校验才会生效。

其他使用方式保持不变。

publicclassConditionUser {/**     * 操作类型     */@Ranges({"create","edit"})privateStringoperType;/**     * 新建时,name 必填     */@EqualsCondition(value ="create",fieldName ="operType")@Size(min =3)@NotNullprivateStringname;/**     * 不是新建时, id 字段必填     */@NotEqualsCondition(value ="create",fieldName ="operType")@Size(min =16)privateStringid;//getter & setter}

过程式接口

说明

日常开发中,我们都很喜欢使用注解对 java bean 进行校验。

但是这回导致我们定义的单个属性校验无法复用。

所以项目中的单个属性校验和注解是一一对应的,为了便于复用。

ValidHelper 方法

ValidHelper 作为统一封装的工具类,提供单个方法校验常见的方法。

和 java bean 类似,方法列表:

序号方法返回值说明
1failOver(Object object, IConstraint constraint)IResult全部验证后返回
2failFast(Object object, IConstraint constraint)IResult快速验证后返回
3failOverThrow(Object object, IConstraint constraint)void全部验证后返回-未通过抛出 ValidRuntimeException 异常
4failFastThrow(Object object, IConstraint constraint)void快速验证后返回-未通过抛出 ValidRuntimeException 异常

使用例子

用法和 bean 的类似,只是入参多了第二个约束条件。

IResultresult =ValidHelper.failFast("",Constraints.notEmpty());

IConstraint 对应关系

注解和常见的接口方法一一对应,所有的约束方法在Constraints 工具类中。

JSR-303 / jakarta bean validation 约束注解支持

序号注解说明对应方法
1@AssertTrue为 true 约束条件assertTrue()
2@AssertFalse为 false 约束条件assertFalse()
3@Null为 null 约束条件nulls()
4@NotNull不为 null 约束条件notNulls()
5@Past是否在当前时间之前约束条件past()
6@PastOrPresent是否在当前时间之前约束条件,包含当前pastOrPresent()
7@Future是否在当前时间之后约束条件future()
8@FutureOrPresent是否在当前时间之后约束条件,包含当前futureOrPresent()
9@Pattern正则表达式约束条件pattern()
10@Size在指定范围内的约束条件size()
11@Digits数字位数的约束条件digits()
12@DecimalMax最大数字的约束条件decimalMax()
13@DecimalMin最小数字的约束条件decimalMin()
14@Min最小的约束条件min()
15@Max最大的约束条件max()
16@NotBlank不能为空格的约束条件notBlank()
17@NotEmpty不能为空的约束条件notEmpty()
18@EmailEmail 约束条件email()
19@Negative指定值必须为负数约束条件negative()
20@NegativeOrZero指定值必须为负数约束条件,包含0negativeOrZero()
21@Positive指定值必须为正数约束条件positive()
22@PositiveOrZero指定值必须为正数约束条件,包含0positiveOrZero()

## hibernate-validator 约束注解支持

实现了常见的几个,后续将陆续完善:

序号注解说明对应方法
1@NotBlank不能为空格的约束条件notBlank()
2@NotEmpty不能为空的约束条件notEmpty()
5@EmailEmail 约束条件email()
3@Length长度的约束条件length()
4@URLURL 约束条件url()
6@UniqueElements元素唯一约束条件uniqueElements()
7@Range指定范围元素约束条件range()

条件注解

注解和常见的接口方法一一对应,所有的约束方法在Conditions 工具类中。

序号注解说明对应方法
1@EqualsCondition等于指定值的条件equals()
2@NotEqualsCondition不等于指定值的条件notEquals()
3@AlwaysTrueCondition永远生效的条件alwaysTrue()
4@AlwaysFalseCondition永远不生效的条件alwaysFalse()

注解自定义

说明

内置的注解,自然无法满足所有的场景。

本项目中,约束和条件注解都是支持自定义的。

约束注解 @Constraint

所有系统的内置注解都可以作为学习的例子。

定义注解

@AllEquals 为例,核心的部分在@Constraint(AtAllEqualsConstraint.class)

我们在 AtAllEqualsConstraint 中实现具体的约束逻辑。

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Constraint(AtAllEqualsConstraint.class)public @interfaceAllEquals {/**     * 当前字段及其指定的字段 全部相等     * 1. 字段类型及其他字段相同     * @return 指定的字段列表     */String[]value();/**     * 提示消息     * @return 错误提示     */Stringmessage()default"";/**     * 分组信息     * @return 分组类     * @since 0.1.2     */Class[]group()default {};}

实现逻辑

推荐直接继承AbstractAnnotationConstraint<A>,实现对应的逻辑即可。

publicclassAtAllEqualsConstraintextendsAbstractAnnotationConstraint<AllEquals> {@OverrideprotectedIConstraintbuildConstraint(AllEqualsannotation) {returnConstraints.allEquals(annotation.value());    }}

条件注解 @Condition

所有系统的内置注解都可以作为学习的例子。

定义注解

@AlwaysTrueCondition 为例,核心的部分在@Condition(AtAlwaysTrueCondition.class)

我们在 AtAlwaysTrueCondition 中实现具体的约束逻辑。

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Condition(AtAlwaysTrueCondition.class)public @interfaceAlwaysTrueCondition {}

实现逻辑

推荐直接继承AbstractAnnotationCondition<A>,实现对应的逻辑即可。

publicclassAtAlwaysTrueConditionextendsAbstractAnnotationCondition<AlwaysTrueCondition> {@OverrideprotectedIConditionbuildCondition(AlwaysTrueConditionannotation) {returnConditions.alwaysTrue();    }}

开源地址

为了便于大家学习使用,目前校验框架已开源。

欢迎大家 fork+star,鼓励一下老马~

validator

ROAD-MAP

  • 优化提示信息

  • springboot 整合

  • i18N 對應的描述信息

  • 更多约束条件

phone

idNo

银行卡

About

🚥Fluent-validation framework for java extend from hibernate-validator.(java 对象属性流式验证框架,下一代校验框架。兼容实现 jakarta bean validation、jsr 303、hibernate-validator)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp