hibernate-validator中@NotBlank不生效的问题分析
文章目录
- hibernate-validator中@NotBlank不生效的问题分析
- 背景介绍
- `@Valid`与`@Validated`
- 常用校验注解说明
- 详细使用
- 问题现象
- 分析思路
- Bean Validation的情况梳理
- Bean Validation的实现
- 猜想原因
- 结论
- 解决方案
- 补充
- Bean Validation - What’s new in 2.0
背景介绍
由于某些历史原因,使用的SpringBoot版本不能超过2.3.
。
为了进行参数的校验。需要使用validation框架,从springboot-2.开始,spring-boot-starter-web
模块中不再引入 spring-boot-starter-validation
,所以需要额外手动引入validation依赖,而 2.3之前的版本只需要引入 web 依赖。
在Spring Boot 项目的 文件中,添加以下依赖
<dependency>
<groupId></groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
@Valid
与@Validated
@Valid
来源于JDK,JSR-380。标注位置在方法上, 字段上, 构造函数上, 参数上, 类型上。包路径:
提示验证框架进行嵌套验证;能配合嵌套验证注解@Valid进行嵌套验证。
@Validated
是是Spring对@Valid
的一次封装,是Spring提供的校验机制。标注位置在范围类上、接口(包括注释类型)上,枚举声明上。包路径:
不能提示验证框架进行嵌套验证;能配合嵌套验证注解@Valid进行嵌套验证。
常用校验注解说明
注解名 | 注解效果 | 注解作用类型 |
---|---|---|
@NotNull | 被注解的元素不能为null,可以为空字符串 | any type |
@NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0) | String |
@NotEmpty | 用在集合类上,不能为null,并且长度必须大于0 | CharSequence,List,Map,Array |
@Size | 被注释的元素的大小必须在指定的范围内。 | CharSequence,List,Map,Array |
@Pattern | 支持,正则的验证。 | Java regular expression |
@Max | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 | BigDecimal BigInteger byte, short, int, long, and their respective wrappers |
@Min | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 | BigDecimal BigInteger byte, short, int, long, and their respective wrappers |
详细使用
百度去吧
问题现象
与
验证的时候无效,但是
与
有效。在这个版本的hibernate-validator上,
与
已经标记为废弃了。这是不合理的。
分析思路
Bean Validation的情况梳理
先去了解Bean Validation的由来
Bean Validation是JSR,规范提案,目前迭代的版本:
Bean Validation 1.0:JSR 303 => /en/jsr/detail?id=303
Bean Validation 1.1:JSR 349 => /en/jsr/detail?id=349
Bean Validation 2.0:JSR 380 => /en/jsr/detail?id=380
Bean Validation的实现
通过Hibernate Validator进行实现规范。在实现上面规范的时候,除了规范约定的约束,还会增加一些常用的Constraint的实现。
是JDK中的约束,而
就是实现的时候补充的一些约束。在迭代的时候,一些注解会先出现在hibernate中,后面规范升级的时候再补充到JDK中。这样就需要去hibernate中检查是否有对应的注解校验器。在
中,bv是基础校验器,hv是hibernate的校验器。
在bv和hv中都存在校验器,说明,上述问题中不同两个包的NotBlank注解都应该可以生效的。在本地springboot中的启动,是可以生效的,而生产环境中却不可以。
Bean Validation的主页:
Bean Validation的参考实现:/hibernate/hibernate-validator
猜想原因
不同的Servlet容器是不是对这个Bean Validation有什么关系?
检查wildfly中 modules中关于Validation的内容。采用的wildfly版本是8(版本真的旧),安装位置是/opt
,那validation
的路径/opt/wildfly/modules/system/layers/base/javax/validation/api/main/
。找到JAR validation-api-1.1.
。发现,规范用的是1.1。检查了一下NotBlank
的规范版本,是2.0。validation-api-1.1.
中并没有。
结论
Bean Validation跟Servlet容器(Tomcat或者Wildfly)的版本是有关的。
说明这个版本的wildfly不支持。
解决方案
- 由于不能升级wildfly,则统一使用
,同时需要梳理出Bean Validation 2.0中增加的哪些注解,都是在不是通过
使用的。
-
@Email
@NotEmpty
,@NotBlank
,@Positive
,@PositiveOrZero
,@Negative
,@NegativeOrZero
,@PastOrPresent
and@FutureOrPresent
-
补充
Bean Validation - What’s new in 2.0
- Support for validating container elements by annotating type arguments of parameterized types, .
List<@Positive Integer> positiveNumbers
(see Container element constraints); this also includes:- More flexible cascaded validation of collection types; . values and keys of maps can be validated now:
Map<@Valid CustomerType, @Valid Customer> customersByType
- Support for
- Support for the property types declared by JavaFX
- Support for custom container types by plugging in additional value extractors (see Value extractor definition)
- More flexible cascaded validation of collection types; . values and keys of maps can be validated now:
- Support for the new date/time data types for
@Past
and@Future
(see Built-in Constraint definitions); fine-grained control over the current time and time zone used for validation (see Implementation of temporal constraint validators) - New built-in constraints:
@Email
,@NotEmpty
,@NotBlank
,@Positive
,@PositiveOrZero
,@Negative
,@NegativeOrZero
,@PastOrPresent
and@FutureOrPresent
(see Built-in Constraint definitions) - All built-in constraints are marked as repeatable now
- Parameter names are retrieved using reflection (see Naming parameters)
-
ConstraintValidator#initialize()
is a default method (see Constraint validation implementation) - The namespace for Bean Validation XML descriptors has been changed to
/xml/ns/validation/configuration
forMETA-INF/
and/xml/ns/validation/mapping
for constraint mapping files (see XML configuration: META-INF/)