在 浅谈SpringMVC之数据绑定 已经介绍了如何获取数据,本文就来介绍一下 SpringMVC 中如何对数据进行校验。
认识 Validation
自 Spring3.0 开始,SpringMVC 提供了对 Java校验API ( Java Validation AP , 又称 JSR-303 ) 的支持,JSR303 是一个标准, 一般会使用它的实现,如 hibernate-validator 。
BTW : 当前已更新至 JSR-380 。
若使用 springboot ,则 spring-boot-starter-web 已包含,本文部分基于 springboot,存在差异( 6.0+ 后包结构改变)。
1 | <!-- hibernate-validator (自动依赖 validation-api) --> |
校验注解
这里介绍一下 javax.validation.constraints
所定义的常用注解,来自 validation-api
。
hibernate-validator
下依然存在许多未过时的校验注解,这里不会介绍。
常用校验注解 | 说明 |
---|---|
@AssertFalse |
限制必须为false。 |
@AssertTrue |
限制必须为true。 |
@DecimalMax(value) |
限制必须为一个不大于指定值的数字。 |
@DecimalMin(value) |
限制必须为一个不小于指定值的数字。 |
@Digits(integer,fraction) |
限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction。 |
@Future |
限制必须是一个将来的日期。 |
@Max(value) |
限制必须为一个不大于指定值的数字。 |
@Min(value) |
限制必须为一个不小于指定值的数字。 |
@NotBlank |
验证注解的元素值不为空(不为null且去除首尾空格后长度为0),不同于@NotEmpty ,@NotBlank 只应用于字符串且在比较时会去除字符串的空格。 |
@NotEmpty |
验证注解的元素值不为 null 且不为空(字符串长度不为0、集合大小不为0)。 |
@NotNull |
限制必须不为 null 。 |
@Null |
限制只能为 null 。 |
@Size(max,min) |
限制字符长度必须在 min 到 max 之间。 |
@Valid 与 @Validated
一般校验注解会作用于 pojo类,而使用 @Valid
或 @Validated
可以通知 Spring 进行校验,校验结果默认以异常抛出或使用 BindingResult
接收。
触发校验注解 | 提供者 | 说明 |
---|---|---|
@Valid |
validation-api | 标记用于验证级联的属性,方法参数或方法返回类型,并且递归应用。符合 JSR303。 |
@Validated |
spring-context | 对 @Valid 的特殊扩展,支持验证组 。支持 JSR303 ,特殊除外。 |
使用 Validation
简单示例
pojo.java
1 | package tk.gushizone.web.validation.controller.dto; |
*Controller.java
在 Spring 中使用 @Valid
或 @Validated
,校验结果信息会被保存到 BindingResult
中。
1 | GET /mvc/validation/valid?name=Foo |
1 | "/valid") ( |
相关提示默认会做国际化兼容,自定义信息需要自己提供。
1 | {id=id不能为空!} |
BindingResult
除了可以获取验证结果,还可以通过 BindingResult
直接注册错误。
1 | GET /mvc/validation/binding-result?name=admin |
1 | "/binding-result") ( |
1 | {name=此名称不允许使用!} |
校验组
定义校验组
校验组接收 Class类,这里以接口为例,利于扩展。
1 | // 编辑校验组 |
使用校验组
pojo.java
pojo 同时用于编辑校验和删除校验。
1 | package tk.gushizone.web.validation.controller.dto; |
*Controller.java
校验时只使用删除校验组。
1 | DELETE /mvc/validation/validated |
1 | "/validated") ( |
1 | {id=id不能为空!} |
自定义 Validation
我们也可以自定义校验规则来满足复杂需求,只需要定义一个校验注解并实现对应的校验实现逻辑类。这里通过一个简单示例来演示一下。
自定义校验注解
使用 @Constraint
来指定校验逻辑类。
也有其他方式,但这种方式最简单直接。
必要属性 | 说明 |
---|---|
message() |
校验提示信息。校验不通过的提示信息。 |
groups() |
校验组。如果有多个校验公用一个 POJO ,可以通过校验组进行区分。 |
payload() |
校验错误级别。类日志的错误级别。 |
1 | package tk.gushizone.web.validation.constraints; |
实现校验逻辑类
校验逻辑实现类需要实现 ConstraintValidator
接口。
1 | package tk.gushizone.web.validation.validator; |
使用示例
*pojo.java
1 | package tk.gushizone.web.validation.controller.dto; |
*Controller.java
1 | GET /mvc/validation/validator?name=foo |
1 | "/validator") ( |
1 | {name=lengthCheck不通过} |
独立校验
如之前所说, Java Validation API 是独立的,可以脱离 springmvc 使用。这里展示一个简单的示例。
ValidationUtils.java
1 | package tk.gushizone.web.validation.util; |
ValidationTest.java
1 | package tk.gushizone.web.validation; |
1 | errorMessages : [id为空, name不能为空] |