请选择 进入手机版 | 继续访问电脑版
本站特色:极好的技术研究氛围!所有技术交流,必有回复!

疯狂Java联盟

 找回密码
 加入联盟
查看: 537|回复: 3

Spring MVC连载(39)-- Spring MVC的数据校验之JSR 303校验

[复制链接]
发表于 2017-12-13 20:08:32 | 显示全部楼层 |阅读模式
本文节选自《Spring+MyBatis企业应用实战》

京东购买地址:https://item.jd.com/12111732.html
本书完整代码下载地址:http://www.crazyit.org/thread-12008-1-1.html
本小节完整代码:codes/06/ValidatorTest

6.4.2 JSR 303校验

JSR 303是Java为Bean数据合法性校验所提供的一个标准规范,叫做Bean Validation。2009年12月Java EE 6 发布,Bean Validation 作为一个重要特性被包含其中,用于对Java Bean中的字段值进行验证。官方参考实现是Hibernate Validator。
Bean Validation 为 JavaBean 验证定义了相应的元数据类型和 API。在应用程序中,通过在Bean属性上标注类似于@NotNull、@Max等标准的注解指定校验规则,并通过标注的验证接口对Bean进行验证。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。
读者可以通过http://jcp.org/en/jsr/detail?id=303了解JSR 303的详细内容。
JSR 303是一个规范,它的核心接口是javax.validation.Validator,该接口根据目标对象类中所标注的校验注解进行数据校验,并得到校验结果。JSR 303目前有两个实现,第一个实现是Hibernate Validator,可以从以下网站下载:

https://sourceforge.net/projects/hibernate/files/hibernate-validator/

第二个实现是Apache bval,可以从以下网站下载:

http://bval.apache.org/downloads.html

JSR 303中定义了一套可标注在成员变量、属性方法上的校验注解,如表6.1所示。
表6.1 JSR 303注解
  注解
  
  功能
  
  范例
  
  @Null
  
  验证对象是否为null
  
  @Null
  String  desc;
  
  @NotNull
  
  验证对象是否不为null,无法检查长度为0的字符串,用于验证基本数据类型
  
  @NotNull
  String  name;
  
  @NotBlank
  
  检查约束字符串是不是Null,被Trim的长度是否大于0。只对字符串,且会去掉前后空格
  
  @NotBlank
  String  name;
  
  @AssertTrue
  
  验证 Boolean 对象是否为 true
  
  @AssertTrue
  boolean  isEmpty;
  
  @AssertFalse
  
  验证 Boolean 对象是否为 false
  
  @AssertFalse
  boolean  isEmpty;
  
  @Max(value)
  
  验证 Number 和 String 对象是否小于等于指定的值
  
  @Max(18)
  Int  age;
  
   
  验证 Number 和 String 对象是否大于等于指定的值
  
  @Max(60)
  Int  age;
  

  注解
  
  功能
  
  范例
  
  @DecimalMax(value)
  
  被标注的值必须不大于约束中指定的最大值.。这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示,小数存在精度
  
  @DecimalMax(1.1)
  BigDecimal price;
  
  @DecimalMin(value)
  
  被标注的值必须不小于约束中指定的最小值.。这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示,小数存在精度
  
  @DecimalMax(0.5)
  BigDecimal price;
  
  @Digits(integer,fraction)
  
  验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度
  
  @Digits(integer=5,fraction=2)
  BigDecimal price;
  
  @Size(min, max)
  
  验证对象(Array、Collection、Map、String)长度是否在给定的范围之内
  
  @Size(min=15, max=60)
  Int age;
  
  @Email
  
  验证是否是合法的邮件地址
  
  @Email
  String email;
  
  @Past
  
  验证 Date 和 Calendar 对象是否在当前时间之前
  
  @Past
  Date birthDate;
  
  @Future
  
  验证 Date 和 Calendar 对象是否在当前时间之后
  
  @Future
  Date shippingDate;
  
  @Pattern
  
  验证 String 对象是否符合正则表达式的规则
  
  @Pattern(regexp="[1][3,8][3,6,9][0-9]{8}")
  String phone;
  

Hibernate Validator是JSR 303的一个参考实现,除了支持所有标准的校验注解之外,它还扩展了如表6.2所示的注解。
表6.2 HibernateValidator扩展的注解
  注解
  
  功能
  
  范例
  
  @URL
  
  验证是否是合法的url
  
  @URL
  String url;
  
  @CreditCardNumber
  
  验证是否是合法的信用卡号码
  
  @CreditCardNumber
  String creditCard;
  
  @Length(min, max)
  
  验证字符串的长度必须在指定的范围内
  
  @Length(min=6, max=8)
  String password;
  
  @NotEmpty
  
  检查元素是否为NULL或者EMPTY。用于Array、Collection、Map、String
  
  @NotEmpty
  String name;
  
  @Range(min,max,message)
  
  验证属性值必须在合适的范围内
  
  @Range(min=18, max=60,message="学生的年龄必须在18岁到60岁之间")
  Int age;
  


示例:测试JSR 303校验
本例使用的是Hibernate Validator的实现,本书成书时最高版本是6.0.5。下载它之后将hibernate- validator-6.0.5.Final.jar、hibernate-validator-annotation-processor-6.0.5.Final.jar、hibernate-validator- cdi-6.0.5.Final.jar和lib/required下的validation-api-2.0.0.Final.jar、javax.el-3.0.1-b08.jar、classmate-1.3.1.jar和jboss-logging-3.3.0. Final.jar加入到项目当中。

程序清单:codes/06/JSR303Test/WebContent/WEB-INF/content/registerForm.jsp
  1. <%@taglib prefix= "form" uri= "http://www.springframework.org/tags/form" %>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <title>测试JSR 303</title>
  6. </head>
  7. <body>
  8. <h3>注册页面</h3>
  9. <form:form modelAttribute="user" method="post" action="login" >
  10.     <table>
  11.         <tr>
  12.             <td>登录名:</td>
  13.             <td><form:input path="loginname"/></td>
  14.             <td><form:errors path="loginname" cssStyle= "color:red"/></td>
  15.         </tr>
  16.         <tr>
  17.             <td>密码:</td>
  18.             <td><form:input path="password"/></td>
  19.             <td><form:errors path="password" cssStyle= "color:red"/></td>
  20.         </tr>
  21.         <tr>
  22.             <td>用户名:</td>
  23.             <td><form:input path="username"/></td>
  24.             <td><form:errors path="username" cssStyle= "color:red"/></td>
  25.         </tr>
  26.         <tr>
  27.             <td>年龄:</td>
  28.             <td><form:input path="age"/></td>
  29.             <td><form:errors path="age" cssStyle= "color:red"/></td>
  30.         </tr>
  31.         <tr>
  32.             <td>邮箱:</td>
  33.             <td><form:input path="email"/></td>
  34.             <td><form:errors path="email" cssStyle= "color:red"/></td>
  35.         </tr>
  36.         <tr>
  37.             <td>生日:</td>
  38.             <td><form:input path="birthDay"/></td>
  39.             <td><form:errors path="birthDay" cssStyle= "color:red"/></td>
  40.         </tr>
  41.         <tr>
  42.             <td>电话:</td>
  43.             <td><form:input path="phone"/></td>
  44.             <td><form:errors path="phone" cssStyle= "color:red"/></td>
  45.         </tr>
  46.         <tr>
  47.             <td><input type="submit" value="提交"/></td>
  48.         </tr>
  49.     </table>
  50. </form:form>
  51. </body>
  52. </html>
复制代码

registerForm.jsp是一个注册页面,用于提交用户注册信息,注册信息包括用户名、密码、邮箱、电话等。之后将在后台使用JSR 303进行验证。

程序清单:codes/06/JSR303Test/src/org/fkit/domain/User
  1. import java.io.Serializable;
  2. import java.util.Date;
  3. import javax.validation.constraints.Past;
  4. import javax.validation.constraints.Pattern;
  5. import javax.validation.constraints.Email;
  6. import org.hibernate.validator.constraints.Length;
  7. import javax.validation.constraints.NotBlank;
  8. import org.hibernate.validator.constraints.Range;
  9. import org.springframework.format.annotation.DateTimeFormat;
  10. public class User implements Serializable{
  11.     @NotBlank(message="登录名不能为空")
  12.     private String loginname;
  13.     @NotBlank(message="密码不能为空")
  14.     @Length(min=6,max=8,message="密码长度必须在6位到8位之间")
  15.     private String password;
  16.     @NotBlank(message="用户名不能为空")
  17.     private String username;
  18.     @Range(min=15, max=60,message="年龄必须在15岁到60岁之间")
  19.     private int age;
  20.     @Email(message="必须是合法的邮箱地址")
  21.     private String email;
  22.     @DateTimeFormat(pattern="yyyy-MM-dd")
  23.     @Past(message="生日必须是一个过去的日期")
  24.     private Date birthDate;
  25.     @Pattern(regexp="[1][3,8][3,6,9][0-9]{8}",message="无效的电话号码")
  26.     private String phone;
  27.     // 省略set/get方法
  28. }
复制代码

User类使用了Hibernate Validator的注解对前台提交的数据进行验证。
程序清单:codes/06/JSR303Test/src/org/fkit/controller/UserController

  1. import javax.validation.Valid;
  2. import org.apache.commons.logging.Log;
  3. import org.apache.commons.logging.LogFactory;
  4. import org.fkit.domain.User;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.ui.Model;
  7. import org.springframework.validation.Errors;
  8. import org.springframework.web.bind.annotation.GetMapping;
  9. import org.springframework.web.bind.annotation.ModelAttribute;
  10. import org.springframework.web.bind.annotation.PostMapping;
  11. @Controller
  12. public class UserController{   
  13.    @GetMapping(value="/registerForm")
  14. public String loginForm(Model model){
  15.     User user = new User();
  16.     model.addAttribute("user",user);
  17.     // 跳转到注册页面
  18.     return "registerForm";
  19. }

  20. // 数据校验使用@Valid,后面跟着Errors对象保存校验信息
  21. @PostMapping(value="/login")
  22.      public String login(
  23.              @Valid @ModelAttribute  User user,
  24.              Errors  errors,
  25.              Model model) {
  26.          logger.info(user);
  27.          if(errors.hasErrors()){
  28.              return "registerForm";
  29.          }
  30.          model.addAttribute("user", user);
  31.          return "success";
  32.      }
  33. }
复制代码

在UserController中使用@Valid注解对提交的数据进行校验,后面跟着Errors对象保存校验信息。如果errors中有错误信息,则返回registerForm页面,验证通过则跳转到success页面。

程序清单:codes/06/ JSR303Test/WebContent/WEB-INF/content/success.jsp
  1. <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <title>测试JSR 303</title>
  6. </head>
  7. <body>
  8. <h3>测试JSR 303</h3>
  9. 登录名:${requestScope.user.loginname }<br>
  10. 密码:${requestScope.user.password }<br>
  11. 用户名:${requestScope.user.username }<br>
  12. 年龄:${requestScope.user.age }<br>
  13. 邮箱:${requestScope.user.email }<br>
  14. 生日:<fmt:formatDate value="${requestScope.user.birthday}"
  15.     pattern="yyyy年MM月dd日"/><br>
  16. 电话:${requestScope.user.phone }<br>
  17. </body>
  18. </html>
复制代码

由于<mvc:annotation-driven/>会默认装配好一个LocalValidatorFactoryBean,因此springmvc- config.xml配置文件中只是基本配置,不需要增加其他的配置。
部署JSR303Test这个Web应用,在浏览器中输入如下URL来测试应用:
  1. http://localhost:8080/JSR303Test/registerForm
复制代码

结果如图6.8所示。
图6.8 测试JSR 303规范.png

输入错误的注册信息,直接单击“提交”按钮,然后后台验证不通过,显示如图6.9所示。
图6.9 测试JSR 303规范.png

输入符合校验规则的注册信息,通过验证后会跳转到成功页面,如图6.10所示。

图6.10 测试JSR 303规范.png


发表于 2017-12-14 18:54:57 | 显示全部楼层
老师,和这本书配套的mybatis视频有吗?
 楼主| 发表于 2017-12-14 21:09:21 | 显示全部楼层
Mryutongxue 发表于 2017-12-14 18:54
老师,和这本书配套的mybatis视频有吗?

你去疯狂软件教育官网www.fkit.org去找MyBatis的配套视频下载。
发表于 2018-7-25 17:35:06 | 显示全部楼层
请问我为什么校验不了,页面一进去年龄就自动给了一个0
什么都不写直接提交也可以跳到success
您需要登录后才可以回帖 登录 | 加入联盟

本版积分规则

小黑屋|手机版|Archiver|疯狂Java联盟 ( 粤ICP备11094030号 )

GMT+8, 2018-10-21 03:26 , Processed in 0.308349 second(s), 7 queries , File On.

快速回复 返回顶部 返回列表