1 JSR- 303
Spring 支持 Java 的 Bean 校验 API( Bean Validation API, 也 被称为 JSR- 303)。
JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现。 Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现。
约束注解名称 | 约束注解说明 |
---|---|
@Null | 验证对象是否为空 |
@NotNull | 验证对象是否为非空 |
@AssertTrue | 验证 Boolean 对象是否为 true |
@AssertFalse | 验证 Boolean 对象是否为 false |
@Min(value) | 验证 Number 和 String 对象是否大等于指定的数字 |
@Max(value) | 验证 Number 和 String 对象是否小等于指定的数字 |
@DecimalMin(value) | 验证 Number 和 String 对象是否大等于指定的数字,存在精度要求 |
@DecimalMax(value) | 验证 Number 和 String 对象是否小等于指定的数字,存在精度要求 |
@Size(max=x, min=y) | 验证对象(Array、Collection、Map、String)长度是否在给定的范围之内 |
@Digits(integer, fraction) | interger指定整数精度,fraction指定小数精度。验证对象是否在指定精度内 |
@Past | 验证 Date 和 Calendar 对象是否在当前时间之前 |
@Future | 验证 Date 和 Calendar 对象是否在当前时间之后 |
@Pattern | 验证 String 对象是否符合正则表达式的规则 |
2 实践
在 Spring MVC 中使用校验功能的步骤是这样的:
- 在需要被校验的 POJO 类上声明校验规则。
- 在 Controller 的具体方法上声明需要校验。
- 表单视图根据校验,展示提示信息。
Craig Walls 举了这样一个示例。填写表单然后提交,如果表单字段校验失败,则提示用户。
(1)POJO 类
我们首先利用 JSR- 303,在需要校验的实体 POJO 类上定义具体每个字段的校验规则。
@Data
public class Taco {
@NotNull
@Size(min = 5, message = "Name must be at least 5 characters long")
private String name;
...
}
(2)Controller 方法
接着在 Controller 方法的具体签名中,给刚才定义校验的 POJO 实体类加上 @Valid 注解。
@Controller
@RequestMapping("/design")
public class DesignTacoController {
@PostMapping
public String processDesign(@Valid @ModelAttribute("design") Taco design, Errors errors){
if(errors.hasErrors()){
return "design";
}
...
}
}
Spring MVC 会对标注了 @Valid 注解的对象进行校验。校验会在这个对象绑定完表单数据之后 、 调用 Controller 方法之前进行。如果不通过校验,那么这些校验错误信息会被捕获到一个 Errors 对象中并传递给具体的 Controller 方法。
通过 errors.hasErrors()
方法,可以在出现校验错误时,将请求跳转到指定视图。
(3)视图层
这里采用了 thymeleaf 视图模板技术。Thymeleaf 是一个XML/XHTML/HTML5模板引擎,类似 Freemarker。
<h3>Name your taco creation:</h3>
<input type="text" th:field="*{name}"/>
<span th:text="${#fields.hasErrors('name')}">XXX</span>
<span class="validationError"
th:if="${#fields.hasErrors('name')}"
th:errors="*{name}">Name Error</span>
运行结果:
- thymeleaf 以
th:
作为属性名前缀。 ${variable}
表达式表示从上下文获取指定变量的值。th:text
标签用于显示文本。th:if
标签用于判定条件。th:errors
标签用于输出校验失败信息。
因为在提交表单时,输入框为空,所以校验失败。因此页面打印出校验失败的布尔值,而且还以 <span>
显示出提示信息。可以看出,实际的 <span>
元素内初始化定义的内容(比如示例中的 Name Error)不重要,最后 thymeleaf 会用实际的提示信息替换掉该值。