您的位置:首页 > 其它

JFinal源码走读_5_Validator校验源码分析

2015-03-19 22:32 796 查看

jfnal特性之Validator后端验证源码探究

所谓Vadidator是什么

public abstract class Validator implements Interceptor


Validator是个抽象类,定义了必备的验证方法,具体的validator只需继承该类即可拥有极简的验证方式,从上面的代码也可以看出,所谓Validator实质上就是一个拦截器

Validator如何使用

官方文档很清晰,不赘言

具体代码分析

以demo中的BlogValidator为切入口,分析validate方法中的validateRequiredString方法的具体行为

protected void validateRequiredString(String field, String errorKey, String errorMessage) {        // 根据方法调用时传递进来的表单域名称,获取对应的值,至于controller是如何可以被获取到的,涉及到Validator作为拦截器的intercept方法
String value = controller.getPara(field);        // 简单的判空操作        if (value == null || "".equals(value.trim()))            // 添加验证失败标志,为request添加error信息
addError(errorKey, errorMessage);
}


validator内部定义了许多验证方法,但是实现思路上与上面并无二致。

Validator的intercept方法
有关于拦截器的intercept方法何时被调用,在运行时初探时已经分析过,下面只关注Validator的intercept方法具体做了些什么

final public void intercept(ActionInvocation invocation) {
Validator validator = null;        try {            // 又见反射,jfinal中无处不有反射的使用,actionmapping时contorller的获取也是如此            // 获取当前validator拦截器的实例
validator = getClass().newInstance();
} catch (Exception e) {            throw new RuntimeException(e);
}        // 初始化validator
validator.controller = invocation.getController();
validator.invocation = invocation;        try {            // 调用 开发者继承重写的validate方法,即上一步分析的内容
validator.validate(validator.controller);
} catch (ValidateException e) {/* should not be throw */
} // short circuit validate need this        if (validator.invalid)            // 验证不通过,测调用开发者继承重写的handleError方法            // handleError如何处理,延后分析
validator.handleError(validator.controller);        else            // 通过,继续递归调用的下一步
invocation.invoke();
}


intercept方法肯定会被调用,而它的逻辑又必须如此写,所以作者将其以final修饰,不希望被开发者修改

#handleError分析
protected void handleError(Controller controller) {        // 本质上就是在request中设置之前从客户端传递过来的model属性,如 blog.title、blog.content等
controller.keepModel(Blog.class);        // 根据请求的地址不同,返回不同的响应
String actionKey = getActionKey();        if (actionKey.equals("/blog/save"))
controller.render("add.jsp");        else if (actionKey.equals("/blog/update"))
controller.render("edit.jsp");
}


小结

validate使用起来很简单也很有效,不过占用了一个action级别的拦截器,而action级别的拦截器用@before注解只能注册一个,如果有多个拦截器需要配置到action级别上,该如何做?使用拦截器栈即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: