本节将会介绍如何使用 Hasor 强大的表单验证功能。在开始正文以前先墨迹两句为何要使用表单验证功能。html
一般一个表单在递交到后台以后咱们在处理表单内容以前会作一些参数合法性校验。好比:年龄大于1,性别必须是:男或女,账号密码输入不能为空。最后还要把验证的信息反馈到页面上。java
Hasor 在设计表单验证功能时候参考了大量具备相似功能的框架,也作了大量 API 上面的设计优化。相信会给您一个很是清爽欢快的体验。好了废话很少说,进入正题。数据库
在 Hasor 中使用表单验证必需要经过 Controller,咱们以登陆场景为例进行说明。首先把各类登陆请求参数传递进来(关于传参能够阅读:https://my.oschina.net/u/1166271/blog/753718)app
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 之间的关系ide
@ValidBy(LoginFormValidation.class) public class LoginForm { ... }
第三步:经过 @Valid 注解告诉 Controller 这个参数须要进行表单验证。post
@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 做为模版渲染引擎spa
<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 页面里。 .net
什么都不填执行递交会看到以下页面:
下面在展现一个稍微酷炫一点的技能,使用多个表单验证器同时为同一个表单进行验证。
编写新的表单验证器来查询数据以验证登陆动做。在执行数据库验证以前,首先判断一下以前的表单验证是否已经经过。若是没有经过,那么就不执行数据库验证。若是验证经过了,就到数据库里查询一下数据。
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.”