一般来说,数据校验由前端jQuery校验,服务端JSR303校验和数据库的约束,这三层共同组成

jQuery前端校验

  • jQuery Validate 插件提供了强大的表单验证功能,能够让客户端表单验证变得更简单,同时它还提供了大量的可定制化选项,以满足应用程序的各种需求。该插件捆绑了一套非常有用的验证方法,包括 URL 和电子邮件验证,同时也提供了API允许用户自定义校验方法。提供的所有捆绑方法默认使用英语作为错误信息,且已翻译成其他 37 种语言
  • 官方网站:https://jqueryvalidation.org/
  • Github项目地址:https://github.com/jquery-validation/jquery-validation

导入JS库

1
2
3
4
<script src="jquery.min.js"></script> 
<script src="jquery.validate.min.js"></script>
<script src="additional-methods.min.js"></script>
<script src="messages_zh.min.js"></script>

在web项目中使用<%=request.getContextPath() %>作为根目录

1
2
3
<script src="http://static.runoob.com/assets/jquery-validation-1.14.0/lib/jquery.js"></script>
<script src="http://static.runoob.com/assets/jquery-validation-1.14.0/dist/jquery.validate.min.js"></script>
<script src="http://static.runoob.com/assets/jquery-validation-1.14.0/dist/localization/messages_zh.js"></script>

默认校验规则

规则 描述
required:true 必须输入的字段
remote:"remote-valid.jsp" 使用 ajax 方法调用 remote-valid.jsp 验证输入值
email:true 必须输入正确格式的电子邮件
url:true 必须输入正确格式的网址
date:true 必须输入正确格式的日期。日期校验 ie6 出错,慎用
dateISO:true 必须输入正确格式的日期(ISO),例如:2009-06-23,1998/01/22。只验证格式,不验证有效性
number:true 必须输入合法的数字(负数,小数)
digits:true 必须输入整数
creditcard: 必须输入合法的信用卡号
equalTo:"#password" 输入值必须和 password 相同
accept: 输入拥有合法后缀名的字符串(上传文件的后缀)
maxlength:5 输入长度最多是 5 的字符串(汉字算一个字符)
minlength:10 输入长度最小是 10 的字符串(汉字算一个字符)
rangelength:[5,10] 输入长度必须介于 5 和 10 之间的字符串(汉字算一个字符)
range:[5,10] 输入值必须介于 5 和 10 之间
max:5 输入值不能大于 5
min:10 输入值不能小于 10

默认提示

  • jQuery Validate提供了中文信息提示包,位于下载包的下载/dist/localization/messages_zh.min.js中,内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*! jQuery Validation Plugin - v1.19.0 - 11/28/2018
* https://jqueryvalidation.org/
* Copyright (c) 2018 Jörn Zaefferer; Licensed MIT */
!(function (a) {
"function" == typeof define && define.amd
? define(["jquery", "../jquery.validate.min"], a)
: "object" == typeof module && module.exports
? (module.exports = a(require("jquery")))
: a(jQuery);
})(function (a) {
return (
a.extend(a.validator.messages, {
required: "这是必填字段",
remote: "请修正此字段",
email: "请输入有效的电子邮件地址",
url: "请输入有效的网址",
date: "请输入有效的日期",
dateISO: "请输入有效的日期 (YYYY-MM-DD)",
number: "请输入有效的数字",
digits: "只能输入数字",
creditcard: "请输入有效的信用卡号码",
equalTo: "你的输入不相同",
extension: "请输入有效的后缀",
maxlength: a.validator.format("最多可以输入 {0} 个字符"),
minlength: a.validator.format("最少要输入 {0} 个字符"),
rangelength: a.validator.format("请输入长度在 {0} 到 {1} 之间的字符串"),
range: a.validator.format("请输入范围在 {0} 到 {1} 之间的数值"),
step: a.validator.format("请输入 {0} 的整数倍值"),
max: a.validator.format("请输入不大于 {0} 的数值"),
min: a.validator.format("请输入不小于 {0} 的数值"),
}),
a
);
});
  • 可以将该本地化信息文件 dist/localization/messages_zh.js 引入到页面:
1
<script src="http://static.runoob.com/assets/jquery-validation-1.14.0/dist/localization/messages_zh.js"></script>

使用方式

1
2
3
4
5
6
7
<form action="#" id="r-form">
<h1>注册</h1>
<p>用户名:<input name="username" type="text" placeholder="昵称"></p>
<p>电子邮箱:<input name="email" type="email" placeholder="电子邮箱"></p>
<p>密码:<input name="password" type="password" placeholder="密码"></p>
<p></button><button id="btn-register">注册</button></p>
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 //$().ready(function(){}) 页面加载完成就调用函数
$().ready(function(){
// 在键盘按下并释放及提交后验证提交表单
$("#r-form").validate({
rules: { //指定规则
username: {
required: true,
minlength: 2,
maxlength: 6,
usernameCheck: true, //usernameCheck为自己制定校验规则的一个函数
},
email: {
required: true,
email: true
},
password: {
required: true,
minlength: 5
}
},
messages: { //回复信息
username:{
required: "请输入用户名",
minlength:"用户名必须有两个字符组成",
maxlength:"用户名最大长度为六个字符"
},
email:{
required: "请输入邮箱地址",
email:"请输入一个正确的邮箱"
},
password: {
required: "请输入密码",
minlength: "密码长度不能小于 5 个字符"
}
}
});
})

//自定义验证规则
jQuery.validator.addMethod("usernameCheck", function (value, element) {
var regExpStr = /^[\u4E00-\u9FA5A-Za-z0-9]+$/;
return regExpStr.test(value);
}, "昵称只支持中文、英文、数字");

发送ajax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 $().ready(function () {
// 在键盘按下并释放及提交后验证提交表单
$("#r-form").validate({
submitHandler:function(){
$.ajax({
url:"http://localhost:8080/register",
type:"post",
data:{
username: $("#r-username").val(),
email:$("#r-email").val(),
password:$("#r-password").val()
},
success:function(result){

}
})
//注意当注册的<button></button>未指定type时表单会默认提交,所以这里要return false;
return false;
}
})
}

JSR303后端校验

  • JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准

导入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--JSR303数据校验支持;tomcat7及以上的服务器-->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>

校验规则

  • Bean Validation 中内置的 constraint
Constraint 详细信息
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
  • Hibernate Validator 附加的 constraint
Constraint 详细信息
@Email 被注释的元素必须是电子邮箱地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range 被注释的元素必须在合适的范围内

数据插入校验

  • 在一个实体类上加验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.netease.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.Pattern;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private int id;
//JSR303后端校验,需要导入Hibernate-Validator包
@Pattern(regexp="(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})"
,message="用户名必须是2-5位中文或者6-16位英文和数字的组合")
private String username;
@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$"
,message="至少8位并包含大小写和数字,不能包含特殊字符")
private String password;
@Pattern(regexp="^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$",
message="用户名@域名(域名后缀至少2个字符)")
private String email;
private int state;
private String code;
private String avatar;
}

  • 然后再 Controller 对应方法上,对这个用户标上 @Valid 注解,表示我们对这个对象属性需要进行验证,并通过BindingResult存放验证结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//接收用户名,密码,邮箱,通过JSR303进行校验
@ResponseBody
@RequestMapping(value="/addUser",method = RequestMethod.POST)
public ReturnMsg addUser(@Valid User user1, BindingResult result){
ReturnMsg returnMsg = new ReturnMsg();
//存入用户名,密码,邮箱
Map<String, Object> map = new HashMap<>();
map.put("username", user1.getUsername());
map.put("password", user1.getPassword());
map.put("email", user1.getEmail());
map.put("avatar",user.getAvatar());
System.out.println(result.hasErrors());
if(result.hasErrors()){
//校验失败,应该返回失败信息
Map<String, Object> resultmap = new HashMap<>();
List<FieldError> errorList = result.getFieldErrors();
for (FieldError fieldError : errorList) {
System.out.println("错误的字段名:"+fieldError.getField());
System.out.println("错误信息:"+fieldError.getDefaultMessage());
resultmap.put(fieldError.getField(), fieldError.getDefaultMessage());
}
returnMsg.add("errorFields",resultmap);
}else {
int i = userService.addUserSelective(map);
if(i>0){
System.out.println("插入成功:"+user.getAvatar());
returnMsg.isSuccess();
}else{
returnMsg.fail("添加失败!");
}
}
return returnMsg;
}
  • 运行结果


  • 然后通过解析JSON对象在失败的回调函数中展示后端提示的错误
1
2
3
4
5
6
7
8
9
10
11
12
if(undefined != result.hashMap.errorFields.username){
//显示用户名字的错误信息
show_validate_msg("#userName_add_input", "error", result.hashMap.errorFields.username);
}
if(undefined != result.hashMap.errorFields.password){
//显示密码错误信息
show_validate_msg("#password_add_input", "error", result.hashMap.errorFields.password);
}
if(undefined != result.hashMap.errorFields.email){
//显示邮箱错误信息
show_validate_msg("#email_add_input", "error", result.hashMap.errorFields.email);
}