文档章节

简单方便的表单验证

哈库纳
 哈库纳
发布于 2016/10/01 17:08
字数 1270
阅读 427
收藏 20

    本节将会介绍如何使用 Hasor 强大的表单验证功能。在开始正文之前先墨迹两句为什么要使用表单验证功能。

    通常一个表单在递交到后台之后我们在处理表单内容之前会做一些参数合法性校验。比如:年龄大于1,性别必须是:男或女,帐号密码输入不能为空。最后还要把验证的信息反馈到页面上。

    Hasor 在设计表单验证功能时候参考了大量具有类似功能的框架,也做了大量 API 上面的设计优化。相信会给您一个非常清爽欢快的体验。好了废话不多说,进入正题。

表单验证

    在 Hasor 中使用表单验证必须要通过 Controller,我们以登录场景为例进行说明。首先把各种登录请求参数传递进来(关于传参可以阅读:https://my.oschina.net/u/1166271/blog/753718)

public class LoginForm {
    @ReqParam("account")
    private String account;
    @ReqParam("password")
    private String password;
    ...
}

@MappingTo("/login.htm")
public class Longin {
    public void execute(@Params LoginForm loginForm, RenderData data) {
        ...
    }
}

    第一步:编写表单验证器。

public class LoginFormValidation implements Validation<LoginForm> {
    @Override
    public void doValidation(String validType, LoginForm dataForm, ValidErrors errors) {
        if (StringUtils.isBlank(dataForm.getAccount())) {
            errors.addError("account", "帐号为空。");
        }
        if (StringUtils.isBlank(dataForm.getPassword())) {
            errors.addError("password", "密码为空。");
        }
    }
}

    第二步:建立表单对象 LoginForm 和验证器 LoginFormValidation 之间的关系

@ValidBy(LoginFormValidation.class)
public class LoginForm {
    ...
}

    第三步:通过 @Valid 注解告诉 Controller 这个参数需要进行表单验证。

@MappingTo("/login.do")
public class Longin {
    public void execute(@Valid() @Params LoginForm loginForm) {
        System.out.println("login data is " + JSON.toString(loginForm));
    }
}

    接下来我们接着改造 Login,让它实现如果表单验证成功我们就跳转到用户详情页。如果验证失败就回到登陆页并提示错误。

@MappingTo("/login.htm")
public class Longin {
    public void execute(@Valid() @Params LoginForm loginForm, RenderData data) {
        if (data.isValid()) {
            data.renderTo("/userInfo.htm");
        } else {
            data.put("loginForm", loginForm);
            data.renderTo("/login.htm");//使用 htm 引擎渲染页面。
        }
    }
}

    剩下的就是login页面处理验证信息回显,这次我们使用 freemarker 作为模版渲染引擎

<form action="/login.do" method="post">
    <!-- 帐号的验证结果 -->
    帐号:<input name="account" type="text" value="${loginForm.account}">
    <#if validData["account"]?? >
        ${validData["account"]?join(",")}
    </#if>
    
    <!-- 密码的验证结果 -->
    密码:<input name="password" type="password" value="${loginForm.password}">
    <#if validData["password"]?? >
        ${validData["password"]?join(",")}
    </#if>
    <input type="submit" value="递交"/>
</form>

    在上面这个例子中,我们还顺便实现了表单内容如果验证失败时在跳转回 login 页面时,自动把上一个login 的页面参数回显到新的 login 页面里。   

    什么都不填执行递交会看到如下页面:

 

使用多个验证器

    下面在展示一个稍微酷炫一点的技能,使用多个表单验证器同时为同一个表单进行验证。

    编写新的表单验证器来查询数据以验证登录动作。在执行数据库验证之前,首先判断一下之前的表单验证是否已经通过。如果没有通过,那么就不执行数据库验证。如果验证通过了,就到数据库里查询一下数据。

public class DataBaseValidation implements Validation<LoginForm> {
    @Inject
    private UserDao userDao;
    @Override
    public void doValidation(String validType, LoginForm dataForm, ValidErrors errors) {
        if (!errors.isValid()) {
            return;//前面的验证没有通过
        }
        //
        String account = dataForm.getAccount();
        String password = dataForm.getPassword();
        UserInfo userInfo = userDao.queryUserInfoByAccount(account);
        if (userInfo == null) {
            errors.addError("login", "登陆失败,不存在的帐号。");
            return;
        }
        if (!StringUtils.equalsIgnoreCase(password, "pwd")) {
            errors.addError("login", "登陆失败,密码错误。");
            return;
        }
        //
    }
}

    为了快速说明表单验证的用法,我使用 UserDao 封装查询数据库操作,而查询数据库操作是一个假查询。查询只是会判断帐号字段是否为“zyc”如果不是zyc返回空,如果匹配成功返回一个新的对象。

public class UserDao {
    public UserInfo queryUserInfoByAccount(String account) {
        if (StringUtils.equalsIgnoreCase(account, "zyc")) {
            return new UserInfo();
        }
        return null;
    }
}

     最后配置一下表单验证器。修改 FormBean 配置多个表单验证器,配置的验证器顺序就是表单验证执行的顺序。第一个验证器执行基本的数据验证,第二个验证器执行数据库验证。

@ValidBy({LoginFormValidation.class, DataBaseValidation.class})
public class LoginForm {
    ...
}

    最后在改造一下login 页面,把所有验证信息都输出到页面上。

<form action="/login.do" method="post">
    <!-- 帐号的验证结果 -->
    帐号:<input name="account" type="text" value="${loginForm.account}">
    <#if validData["account"]?? >
        ${validData["account"]?join(",")}
    </#if>
    <br/>

    <!-- 密码的验证结果 -->
    密码:<input name="password" type="password" value="${loginForm.password}">
    <#if validData["password"]?? >
        ${validData["password"]?join(",")}
    </#if>
    <br/>
    <!-- 登陆处理结果 -->
    <#if validData["login"]?? >
        ${validData["login"]?join(",")}<br/>
    </#if>

    <input type="submit" value="递交"/><br/>
</form>

    运行一下程序,访问登录页面执行登录。

    1. 如果什么都没有填写执行登录,我们可以看到提示,帐号为空,密码为空。

    2.如果帐号和密码都不为空,那么会执行第二个验证器。在第二个验证器中只有正确输入了

        帐号:“zyc”,密码“pwd”。才会登录成功,否则都会提示错误。下面让我们看看执行结果。

    3.随便输入帐号和密码。

    4.帐号输入“zyc”正确,密码随便输入。

    5.输入正确的帐号和密码,可以看到页面提示出“Hello You.”

© 著作权归作者所有

共有 人打赏支持
哈库纳

哈库纳

粉丝 962
博文 84
码字总数 151810
作品 4
杭州
后端工程师
私信 提问
jQuery validate插件初探

jQuery的validate插件,在jQuery验证时使用非常方便。 具体使用步骤: 1.引入文件 既然是jQuery插件,必须要有jQuery作为支持jquery-1.3.2.min.js 然后是验证的核心文件jquery.validate.js ...

桃子红了呐
2017/07/07
0
0
Javascript之return

做表单验证的时候,除了错误提示之外,还要做的一点就是避免表单提交。 如果避免表单提交呢? 有一个方法很简单,就是return 我们来看一下代码: $(".make_sure").click(function(){ 这是表单...

桃子红了呐
2017/06/25
0
0
20个jQuery插件,帮你打造完美网页表单

网页表单主要是用来从用户那里收集一些必要的信息,是网页设计中不可或缺的一环。一个设计良好的表单能更有效的获取用户信息,也会给用户带来更好地使用体 验。基于这一点,很多设计师开始使...

鉴客
2012/03/31
4.8K
13
拜读及分析Element源码-form表单组件篇

element from表单源码分析,涉及到input、select、checkbox、picker、radio等组件的的验证。表单的验证用到了async-validator 插件。一起来看看吧。 form: 统一管理form-item。 form-item:负...

hollyDysania
09/13
0
0
jQuery之validate验证表单

访问jQuery validate官网下载最新插件 https://jqueryvalidation.org/ validate是用来验证表单的 以前我们都是用js手动验证 现在可以通过这个插件直接调用别人写好的方法 更加简单方便 vali...

codingcoge
05/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

nuc970 uboot nand-boot,kernel, filesystem 烧录位置

一 烧写到Nand Flash **1.1 **相关文件说明 l BSP版本:nuc970bsp-release-20150519.zip l NuWriter版本:2015/04/28-V01,nuvoTon Nu-Writer V1.0 l 烧写文件: u-boot-spl.bin:负责将u-b......

CookieDemo
今天
1
0
python中sort和sorted函数小结

L.sort(cmp=None, key=None, reverse=False) sorted(iterable, cmp=None, key=None, reverse=False) 这样看,sorted函数只比sort函数多一个iterable参数,其余没什么不同,iterable是一个迭代......

上官夏洛特
今天
4
0
thinkphp 常用SQL执行语句总结

第一条:Db::tablera('vr_panomas')->where(['delete_time'=>0,'id'=>['in',$pids]])->field(['id'=>'id','post_thumb'=>'thumb','post_title'=>'title','post_tags'=>'tags','post_price'=>......

koothon
今天
6
0
支付宝返回状态resultStatus意思

上一篇集成支付宝的时候,会有一些支付宝返回的resultStatus,具体意思是: 9000 订单支付成功 8000 正在处理中 4000 订单支付失败 6001 用户中途取消 6002 网络连接出错 还有memo,意思就是...

RainOrz
今天
4
0
electron webview 页面加载事件顺序

1.did-start-loading 页面开始加载 2.load-commit 主页面文档加载 3.page-title-updated title 4.dom-ready 主页面 dom 加载完成 5.load-commit frame文档加载 6.did-frame-finish-load fram......

dubox
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部