Spring MVC 表单验证
1. 前言
本节课讲解 Spring MVC 提供的验证框架,这个验证框架属于服务器端验证模式。通过本章节内容的学习,你将理解 JSR 概念,并能学到验证框架所提供的注解。
本章节重点是掌握 JSR 验证框架的使用;难点是理解其实现原理。
2. JSR
数据验证是对数据进行逻辑处理之前需要进行的一个很重要环节,如果不合要求的数据进入逻辑处理环节后,会导致程序的崩溃。
WEB 应用程序中,验证用户提交的表单数据的合法性既可以在客户端实现,也可以在服务器端实现。
- 客户端验证: 表单提交之前,通过客户端的 JS 脚本对表单中预提交的数据进行验证;
- 服务器端验证: 数据提交到服务器后,由服务器端的的代码进行验证。
对于非敏感性的数据可以在客户端验证,如一些常规性的输入格式要求验证、类似于密码长度要多少、信息不能为空等。
服务器端相比较于客户端验证,会多出网络流量消耗。但是,对于一些敏感性的数据,比如身份证信息、银行卡信息…… 还是需要交给服务器的。
Spring MVC 提供的有验证框架,能够在绑定请求包中的数据时,按开发者提出的格式验证规则对数据进行验证。Spring MVC 验证框架的使用非常便利,只需要几个注解就能轻松解决问题。
使用之前,有几个概念先要交代清楚。
2.1 JSR 是什么
Tips: 不要看错了,是 JSR 不是 JSP。
JSR: Java 官方提供的数据合法性标准验证框架,它只是一个规范。现有多个版本:
- Bean Validation 2.0 (JSR 380) ;
- Bean Validation 1.1 (JSR 349);
- Bean Validation 1.0 (JSR 303)。
准确的讲,Spring MVC 验证框架只是集成了 JSR 验证框架,并没有太多自己的具体实现。 JSR 提供了很多验证注解,一般放在要验证的 Bean 类型的属性前面。
- @Null: 被注解的属性的值必须为空;
- @NotNull: 被注解的属性的值可以不为空;
- @Min(value): 注解数字类型的属性,其值大于等于指定的值;
- @Max(value): 注解数字类型的属性,其值小于等于指定值;
- @Size(max, min): 注解的属性值的大小必须是在给定的范围内(包括边界数字);
- @Past: 注解日期类型属性,必须是一个过去的日期;
- @Future: 注解日期类型属性,必须是一个将来的日期;
- @Pattern(regexp): 使用正则表达式验证属性的值;
- @Length(min,max): 属性值的长度在给定的范围之内(包括边界数字)。
Tips: 更多的验证注解大家可以查阅 JSR 官方文档。
了解了这些注解后,现在开始使用。
2.2 使用验证框架
2.2.1 验证前的准备
打开项目中的 pom.xml 文件,添加 validation-api 依赖包,大家需要注意一下,包名是以 javax 开头的。因为 Spring MVC 并没有实现 JSR 接口规范,这里选择 hibernate-validator ;
Tips: hibernate-validator 是 Hibernate 提供的 JSR 具体实现模块。
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
打开 WebConfig 配置类,通知 Spring MVC 创建 LocalValidatorFactoryBean 对象。可以使用这个工厂对象创建具体的实现了 JSR 规范的验证器。
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setProviderClass(HibernateValidator.class);
return localValidatorFactoryBean;
}
2.2.2 JSR 验证流程
先设定一个需求:添加老师信息。
- 构建一个 Teacher 类,并在 Teacher 类的相关属性上添加对应注解;
public class Teacher {
@NotNull(message = "姓名不能为空")
private String name;
@Min(value = 22,message = "年龄不能小于 22 岁")
private Integer age;
Tips: JSR 注解有一个 message 属性,用来保存错误提示信息。
- 编写 teacher.html 页面;
<form action="teacher/save" method="post">
老师姓名:<input type="text" value="" name="name"/>
<br/>
老师年龄:<input type="text" value="" name="age"/>
<br/>
<input type="submit" value="添加" name="btnSave"/>
<input type="reset" value="重置" name="btnReset"/>
</form>
- 编写响应控制器;
@Controller
@RequestMapping("/teacher")
public class TeacherAction {
@RequestMapping(value = "/save",method = RequestMethod.POST)
public String register(@Valid Teacher teacher,BindingResult result) {
if (result.hasErrors()) {
return "fail";
}
return "success";
}
}
Tips: @Valid 注解表示在绑定数据之后对数据进行验证。BindingResult 组件用来保存验证过程中的错误信息。除了可以使用 BindingResult ,此处还可以使用 Errors 替代。
- 在浏览器中访问到 teacher.html 页面,输入不符合规则的数据后提交(年龄小于 22 岁);
- 最后会在浏览器中看到。
如此,整个验证过程完毕。
3. 显示错误信息
前面的测试过程有一个遗憾,没有看到错误信息,没有明确的告诉使用者哪些数据输入没有符合验证要求。
要实现这个功能,只需要在控制器中把错误信息保存到请求域,然后在页面中显示出来。
- 修改一下控制器中的代码。比前面的代码多了一个 ModelMap 对象,用于把错误信息保存到请求作用域中;
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String register(@Valid Teacher teacher, BindingResult result, ModelMap model) {
if (result.hasErrors()) {
List<FieldError> fieldsErrors = result.getFieldErrors();
for (FieldError fieldError : fieldsErrors) {
model.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return "fail";
}
return "success";
}
Tips: 如果验证失败,错误提示信息会自动保存到 BindingResult 类型 。
- 在提交失败的页面中显示错误。
<body>
老师注册失败原因!
<br/>
${name}
<br/>
${age}
</body>
Tips: EL 表达式中的 name、age 是表单提交时的参数名(也就是表单控件的名字)。
model.put (fieldError.getField (), fieldError.getDefaultMessage ()) 这行代码会把错误信息以表单控件名为 key 保存在请求作用域中。
- 再次在浏览器中打开 teacher.html 页面,输入不符合规则的数据,提交后在错误页面中看到。
4. 小结
本节课程和大家讲解了 Spring MVC 的验证框架,需要知道以下 2 点:
- Spring MVC 验证框架采用的是服务器端验证模式;
- Spring MVC 框架集成了 JSR 验证框架,并没有提供具体的实现,本课程使用的是 Hibernate 提供的 JSR 具体实现模块。
Spring MVC 验证框架以注解的方式对数据进行规则限制,方便,简洁,但因是服务器端验证,所以,对于一般性的、常规性的验证建议放在客户端完成。
- 还没有人评论,欢迎说说您的想法!