请求验证

一个请求在递交到后台之后正式处理之前会做一些参数合法性校验。比如:年龄大于1,性别必须是:男或女,帐号密码输入不能为空等。最后还要把验证的信息反馈到页面上,Hasor 的验证器可以帮助实现这些功能

以登录场景为例,首先定义请求参数组:

  1. public class LoginForm {
  2. @RequestParameter("account")
  3. private String account;
  4. @RequestParameter("password")
  5. private String password;
  6. ...
  7. }

然后编写验证器

  1. public class LoginFormValidation implements Validation<LoginForm> {
  2. @Override
  3. public void doValidation(String validType,
  4. LoginForm dataForm,
  5. ValidInvoker errors) {
  6. if (StringUtils.isBlank(dataForm.getLogin())) {
  7. errors.addError("login", "帐号不能为空!");
  8. return;
  9. }
  10. if (StringUtils.isBlank(dataForm.getPassword())) {
  11. errors.addError("password", "密码不能为空!");
  12. return;
  13. }
  14. }
  15. }

接着建立参数组和验证器之间的关系

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

最后通过 @Valid 注解配置请求在接收处理之前先做一次验证:

  1. @MappingTo("/login.htm")public class Login { public void execute(@Valid() @ParameterGroup LoginForm loginForm, RenderInvoker invoker, ValidInvoker valid) { if (valid.isValid()) { invoker.renderTo("/userInfo.htm"); } else { invoker.put("loginForm", loginForm); invoker.renderTo("/login.htm"); } }}

剩下的就是页面处理验证信息回显(freemarker 模板语法)

  1. <form action="/login.do" method="post">
  2. <!-- 帐号的验证结果 -->
  3. 帐号:<input name="account" type="text" value="${loginForm.account}">
  4. <#if validData["account"]?? >
  5. ${validData["account"]?join(",")}
  6. </#if>
  7.  
  8. <!-- 密码的验证结果 -->
  9. 密码:<input name="password" type="password" value="${loginForm.password}">
  10. <#if validData["password"]?? >
  11. ${validData["password"]?join(",")}
  12. </#if>
  13. <input type="submit" value="递交"/>
  14. </form>

多个验证器共同验证

有些校验逻辑比较通用,可以提取成公共的校验逻辑。这样请求验证就可以是 公共 + 制定 两部分组成,如下:

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

验证场景化

场景化,是指在执行验证时。开发者可以通过传给表单验证器的场景名称,进行必要的逻辑判断:

  • doValidLogin、负责处理登录

  • doValidSignUp、负责处理注册

public class LoginFormValidation4Scene implements Validation<LoginForm4Scene> {
    //
    // - 登录验证
    private void doValidLogin(LoginForm4Scene dataForm, ValidInvoker errors) {
        ...
    }
    // - 注册登录
    private void doValidSignUp(LoginForm4Scene dataForm, ValidInvoker errors) {
        ...
    }
    //
    public void doValidation(String validType, LoginForm4Scene dataForm, ValidInvoker errors) {
        // -通用验证逻辑
        if (StringUtils.isBlank(dataForm.getAccount())) {
            errors.addError("account", "帐号为空。");
        }
        if (StringUtils.isBlank(dataForm.getPassword())) {
            errors.addError("password", "密码为空。");
        }
        if (!errors.isValid()) {
            return;
        }
        // -场景化差异
        if (StringUtils.equalsIgnoreCase("signup", validType)) {
            this.doValidSignUp(dataForm, errors);   // 注册
            return;
        }
        if (StringUtils.equalsIgnoreCase("login", validType)) {
            this.doValidLogin(dataForm, errors);    // 登录
            return;
        }
    }
}

最后,在使用验证时,在 @Valid 注解上设定好要使用的场景名称,就可以了。

@MappingTo("/scene/login.do")public class Login4Scene {    public void execute(@Valid("login") @ParameterGroup LoginForm4Scene loginForm,                        RenderInvoker invoker,                        ValidInvoker valid) {        …    }}