“萧萧几叶风兼雨,离人偏识长更苦”
前言
JSR303是Java为Bean数据合法性校验所提供的一个标准规范,叫做 Bean Validation。2009年12月 Java EE6发布, Bean Validation作为一个重要特性被包含其中,用于对 Java Bean中的字段值进行验证。官方参考实现是 Hibernate Validator。
Bean Validation为 JavaBean验证定义了相应的元数据类型和API。在应用程序中,通过在Bean属性上标注类似于 @NotNull,@Max等标准的注解指定校验规则,并通过标注的验证接口对Bean进行验证。 Bean Validation是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。
JSR303注解
注解 | 功能 |
---|---|
@Notnull | 验证对象是否不为mul,无法检査长度为0的字符串,于验证基本数据类型 |
@Null | 验证对象是否为null |
@AssertTrue | 验证 Boolean对象是否为true |
@AssertFalse | 验证 Boolean对象是否为false |
@Max(value) | 验正Number和String对象是否小于等于指定的值 |
@Min(value) | 验正Number和String对象是否大于等于指定的值 |
@DecimalMax(value) | 被标注的值必须不大于约束中指定的最大值。这个约束的参数是一个通过 Big Decimal定义的最大值的字符串表示,小数存在精度 |
@DecimalMin(value) | 被标注的值必须不小于约束中指定的最小值。这个约束的参数是一个通过 Big Decimal定义的最小值的字符串表示,小数存在精度 |
@Digits(integer, fraction) | 验证字符串是否是符合指定格式的数字, Interger指定整数精度, fraction指定小数精度 |
@Size(min, max) | 验证对象(Array、Collection、Map、 String)长度是否在给定的范围之内 |
@Past | 验证Date和 Calendar对象是否在当前时间之前 |
@Pattern | 验证 String对象是否符合正则表达式的规则 |
@NotBlank | 检查约束字符串是不是Null,被Trim的长度是否大于0。只对字符串,且会去掉前后空格 |
@URL | 验证是否是合法的url |
验证是否是合法的邮件地址 | |
@CreditCardNumber | 验证是否是合法的信用卡号码 |
@Length(min, max) | 验证字符串的长度必须在指定的范围内 |
@NotEmpty | 检査元素是否为NULL或者 EMPTY。用于Array、Collection、Map、 String |
@Range(min, max, message) | 验证属性值必须在合适的范围内 |
测试
- 因为JSR303的实现是参考的Hibernate Validator,所以除了springMVC的jar包之外,使用JSR303还需要导入Hibernate 的几个jar包,它们分别是:
classmate-1.1.0.jar、jboss-logging-3.2.1.Final.jar、hibernate-validator-5.2.4.Final.jar、hibernate-validator-annotation-processor-5.2.4.Final.jar、hibernate-validator-cdi-5.2.4.Final.jar、validation-api-1.1.0.Final.jar
- 创建java bean类,并使用注解:
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
import java.util.Date;
/**
1. @author aRunner
2. @date 2018/10/27
*/
public class User implements Serializable {
@NotBlank(message = "登录名不能为空")
private String loginname;
@NotBlank(message = "密码不能为空")
@Length(max = 8,min = 6,message = "密码长度必须在6位到8位之间")
private String password;
@NotBlank(message = "用户名不能为空")
private String username;
@Range(min = 15,max = 60,message = "年龄必须在15岁到60岁之间")
private String age;
@Email(message = "必须是合法的邮箱地址")
private String email;
@DateTimeFormat(pattern = "yyyy-MM-dd")
@Past(message = "生日必须是一个过去的日期")
private Date birthday;
@Pattern(regexp = "[1][3,8][3,6,9][0-9]{9}",message = "无效的电话号码")
private String phone;
//这里省略了get/set方法
}
- Controller类:
//数据校验使用@Valid,后面跟着Errors对象保存校验信息
@RequestMapping(value = "/login",method = RequestMethod.POST)
//@Valid之后必须是Errors 或其实现类
public String login(@Valid @ModelAttribute User user, Errors errors,Model model) {
logger.info(user);
//如果验证不通过跳转到loginForm视图
if (errors.hasFieldErrors()) {
return "registerForm";
}
model.addAttribute("user",user);
return "success";
}
这里有一点需要特别注意,就是在controller类中,紧接着@Valid 之后的参数必须是Errors(如上面实例)或者是Errors的实现类,否则spring会在校验不通过时直接抛出异常。
4. 验证不通过时,再返回页面展示错误信息
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix= "form" uri= "http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试JSR 303</title>
</head>
<body>
<h3>注册页面</h3>
<form:form modelAttribute="user" method="post" action="login" >
<table>
<tr>
<td>登录名:</td>
<td><form:input path="loginname"/></td>
<td><form:errors path="loginname" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>密码:</td>
<td><form:input path="password"/></td>
<td><form:errors path="password" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>用户名:</td>
<td><form:input path="username"/></td>
<td><form:errors path="username" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>年龄:</td>
<td><form:input path="age"/></td>
<td><form:errors path="age" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>邮箱:</td>
<td><form:input path="email"/></td>
<td><form:errors path="email" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>生日:</td>
<td><form:input path="birthday"/></td>
<td><form:errors path="birthday" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>电话:</td>
<td><form:input path="phone"/></td>
<td><form:errors path="phone" cssStyle= "color:red"/></td>
</tr>
<tr>
<td><input type="submit" value="提交"/></td>
</tr>
</table>
</form:form>
</body>
</html>
- 测试结果: