本节将会介绍如何使用 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.”
来源:oschina
链接:https://my.oschina.net/u/1166271/blog/754087