章节列表
- 第一章:使用Validator做SpringMVC的验证框架 - 配置SpringMVC环境
- 第二章:使用Validator做SpringMVC的验证框架 - 使用Validator
- 第三章:使用Validator做SpringMVC的验证框架 - Validator前端验证
- 第四章:使用Validator做SpringMVC的验证框架 - 自定义验证组件
前面的几章已经为大家简单的介绍了Validator的功能已经使用方法,下面接着为大家介绍怎么使用Validator自定义验证组件
Validator框架源码地址:https://github.com/devefx/validator
1 - 创建后台验证组件
大家可能发现了,我们前面的注册功能少了一个很重要的参数,那就是验证码。众所周知验证是为了防止机器人恶意注册的,这一步的验证是需要与服务器进行数据交互的验证,不是简单数据格式判断就能知道正误的。下面我让大家看看Validator框架强大的扩展性
首先修改一下register.jsp,在“个人主页”下面添加一个”验证码“
<tr>
<td>个人主页:</td>
<td><input name="homepage"></td>
</tr>
<!-- 验证码输入框 -->
<tr>
<td>验证码:</td>
<td><input name="code" placeholder="请输入1234"></td>
</tr>
接着我们创建一个“com.devefx.website.validator.constraints”包用来放我们自定义的后台验证组件,同时创建一个java源码文件“CodeValidator”作为验证码验证组件。
CodeValidator.java
package com.devefx.website.validator.constraints;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.devefx.validation.annotation.BindScript;
import com.devefx.validation.constraints.FieldValidator;
import com.devefx.validation.kit.StrKit;
import com.devefx.validation.script.JavaScript;
/**
* 自定义验证码验证器.
*/
public class CodeValidator extends FieldValidator {
private final String sessionKey;
public CodeValidator(String field, String sessionKey, String errorCode, String errorMessage) {
super(field, errorCode, errorMessage);
this.sessionKey = sessionKey;
}
@Override
public boolean isValid(HttpServletRequest request) throws Exception {
String value = request.getParameter(field);
// 如果是空,就交个NotEmptyValidator组件
if (!StrKit.isEmpty(value)) {
HttpSession session = request.getSession();
// 为了讲解方便(实际项目中可不能这么干),我直接把‘1234’当做正确的验证码
return value.equals(/*session.getAttribute(sessionKey)*/"1234");
}
return true;
}
}
好了,这样一个后台验证组件就开发完成了,接着我们就在RegisterValidator.java中使用吧
RegisterValidator.java
package com.devefx.website.validator;
import com.devefx.validation.Validator;
import com.devefx.validation.constraints.impl.EmailValidator;
import com.devefx.validation.constraints.impl.EqualFieldValidator;
import com.devefx.validation.constraints.impl.LengthValidator;
import com.devefx.validation.constraints.impl.MobileValidator;
import com.devefx.validation.constraints.impl.NotBlankValidator;
import com.devefx.validation.constraints.impl.URLValidator;
import com.devefx.website.validator.constraints.CodeValidator;
public class RegisterValidator extends Validator {
@Override
public void setup() {
// 用户名验证
add(new NotBlankValidator("username", "username", "用户名不能为空"));
add(new LengthValidator("username", 6, 20, "username", "用户名长度限制6至20位"));
// 密码验证
add(new NotBlankValidator("password", "password", "密码不能为空"));
add(new LengthValidator("password", 6, 20, "password", "密码长度限制6至20位"));
add(new EqualFieldValidator("password_safe", "password", "password_safe", "两次密码不一致"));
// 手机号验证
add(new NotBlankValidator("phoneno", "phoneno", "手机号不能为空"));
add(new MobileValidator("phoneno", "phoneno", "请输入正确的手机号"));
// 邮箱验证
add(new NotBlankValidator("email", "email", "邮箱不能为空"));
add(new EmailValidator("email", "email", "请输入正确的邮箱"));
// 个人主页验证
add(new URLValidator("homepage", "homepage", "请输入正确的主页地址"));
// 验证码验证
add(new NotBlankValidator("code", "code", "验证码不能为空"));
add(new CodeValidator("code", "registerCode", "code", "请输入正确的验证码"));
}
}
我们启动项目试验一下吧,首先我们输入一个错误的验证码
我们可以发现Validator这时候并没有帮我们立即验证验证码是否正确
上面的图可以看出:只有在其他参数正确的情况下,并进行提交的时候才开始检查出验证码有误,这是因为我们只为他编写了后台验证码,而没有前台验证器的时候实际上分成了两批验证。
2 - 编写前端验证组件代码
前端验证器组件也遵循统一规范,首先我们创建一个“com.devefx.website.validator.constraints.js”包,再新建一个CodeValidator.js文件
CodeValidator.js
function CodeValidator(field, sessionKey, errorCode, errorMessage) {
FieldValidator.apply(this, [field, errorCode, errorMessage]);
this.isValid = function (request, control) {
var value = request.getParameter(field);
if (!isEmpty(value)) {
// 使用异步
control.async();
// ajax异步请求
$.ajax({
url: "/module/code", // 验证接口访问地址
type: "post", // 请求方式
data: {"sessionKey": sessionKey, "code": value},
success: function (result) {
// 根据接口返回结果再同步到验证器
if (result == "success") {
return control.sync(true);
}
control.sync(false);
}
});
}
return true;
};
}
第一行声明了一个函数,此函数名称必须与需要绑定的Java验证组件名称相同,参数含义与Java验证组件的构造函数相同
第二行代码是js中继承的实现,我们同样继承FieldValidator
第三行实现了验证方法。
isValid(request[, control]) 方法
参数 | 说明 |
---|---|
request | 用来获取请求的参数值 |
control | 可选,当此验证需要异步执行的时候,用来获取控制权 |
参数
request
类型:Request
Request提供getParameter(name)方法,可以通过input的name获取input的value
control
类型:Object
提供async、sync(valid)两个方法,async获取到控制权;sync(valid)交还控制权同时告知验证结果
我们可以看到上面定义是前端验证器需要/module/code接口的支持。
我们在“com.devefx.website”包里面创建一个Java源码
ValidatorController.java
package com.devefx.website.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.devefx.validation.ConstraintValidator;
import com.devefx.website.validator.constraints.CodeValidator;
@Controller
@RequestMapping("/module")
public class ValidatorController {
/**
* 检测验证码是否输入正确
*
* @param sessionKey 会话中验证码对应的key
* @return String
*/
@ResponseBody
@RequestMapping(value="/code", method=RequestMethod.POST)
public String codeValidate(HttpServletRequest request,
@RequestParam("sessionKey") String sessionKey) {
try {
ConstraintValidator validator = new CodeValidator("code", sessionKey, null, null);
// 如果验证通过
if (validator.isValid(request)) {
return "success";
}
} catch (Exception e) {
// ignore
}
return "fail";
}
}
注意:上面的sessionKey,我们是为了方便登录、注册共用才保留的,你们可以根据实际情况决定是否使用
3 - 为后台验证组件实现并、绑定前端验证组件
我们修改一下CodeValidator.java文件,给他实现Script接口,并绑定前端组件
CodeValidator.java
package com.devefx.website.validator.constraints;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.devefx.validation.Script;
import com.devefx.validation.annotation.BindScript;
import com.devefx.validation.constraints.FieldValidator;
import com.devefx.validation.kit.StrKit;
import com.devefx.validation.script.JavaScript;
/**
* 自定义验证码验证器.
*/
@BindScript("com/devefx/website/validator/constraints/js/CodeValidator.js")
public class CodeValidator extends FieldValidator implements Script {
private final Script script;
private final String sessionKey;
public CodeValidator(String field, String sessionKey, String errorCode, String errorMessage) {
super(field, errorCode, errorMessage);
this.sessionKey = sessionKey;
script = JavaScript.create(this, field, sessionKey, errorCode, errorMessage);
}
@Override
public boolean isValid(HttpServletRequest request) throws Exception {
String value = request.getParameter(field);
// 如果是空,就交个NotEmptyValidator组件
if (!StrKit.isEmpty(value)) {
HttpSession session = request.getSession();
// 为了讲解方便(实际项目中可不能这么干),我直接把‘1234’当做正确的验证码
return value.equals(/*session.getAttribute(sessionKey)*/"1234");
}
return true;
}
public void output(Writer out) throws IOException {
script.output(out);
}
}
通过@BindScript注解将前端验证组件绑定给后台验证组件,同时实现Script接口用来输出前端调用代码
4 - 注册自定义组件
做完上面的步骤,我们已经到最后一步了,打开Config.java文件
Config.java
package com.devefx.website.validator.config;
import com.devefx.validation.web.config.Modules;
import com.devefx.validation.web.config.Routes;
import com.devefx.validation.web.config.ValidatorConfig;
import com.devefx.website.validator.RegisterValidator;
import com.devefx.website.validator.constraints.CodeValidator;
public class Config implements ValidatorConfig {
public void configModules(Modules modules) {
// 这里可以添加自定义验证组件
// 注册自定义组件
modules.add(CodeValidator.class);
}
public void configRoute(Routes routes) {
// 这里配置验证器的访问路线
// 设置基准路径
routes.setBasePath("/validator");
// 注册验证器
routes.add("/registerValidator.js", RegisterValidator.class);
}
}
大功告成,重启一下项目来看看效果吧。
可以看到我们自定义的验证组件已经能立即进行验证了。
5 - 后语
上面我只为大家介绍了一种自定义验证组件,大家应该还能想到更多用法。
比如:用户名是否重名验证、必须登陆验证、访问权限验证等等。
基本上Validator全部的功能我已经接受完毕,由于是第一次写博客教程,或许很多地方介绍的不够详细,如果大家有什么不明白之处可以通过下面的评论功能或者加入【Java技术交流群】