校验
使用Mentawai你可以在action内利用Validatable接口进行校验,也可以创建一个单独的过滤器完成这项功能。在实际使用中会更倾向于第一种方式。下面是一个例子:
在应用管理器中建立过滤器
@Override
public void loadFilters() {
filter(new ValidationFilter());
}
在action中进行校验
public class UserAction extends BaseAction implements Validatable {
private final UserDAO userDAO;
public UserAction(UserDAO userDAO) {
this.userDAO = userDAO;
}
// Validate the fields for the user form...
@Override
public void prepareValidator(Validator val, String method) {
// NOTE: Instead of i18n keys, you can type the full error message if you don't want to use internationalization
// and store the error messages in a separate file that can be later translated.
// so instead of:
// val.add("email", EmailRule.getInstance(), "bad_email");
// you can have:
// val.add("email", EmailRule.getInstance(), "Please type a valid email address!");
String username_regex = "^[A-Za-z][A-Za-z0-9\\-\\_\\.]*[A-Za-z0-9]$";
if (method != null && method.equals("add") && isPost()) {
val.requiredFields("required_field", "username", "password", "email", "groupId", "languageId"); // varargs for field names
val.requiredLists("required_field", "groupId", "languageId"); // varargs for field names
val.add("username", RegexRule.getInstance(username_regex), "bad_username"); // validates using any regex
val.add("username", MethodRule.getInstance(this, "checkUsernameAdd"), "username_already_exists"); // call any action method to validate
val.add("email", EmailRule.getInstance(), "bad_email"); // special rule with a good email regex
val.add("password", EqualRule.getInstance("password", "passconf"), "pass_no_match"); // compare two fields to validate
} else if (method != null && method.equals("edit") && isPost()) {
val.requiredFields("required_field", "username", "email", "groupId");
val.requiredLists("required_field", "groupId");
val.add("username", RegexRule.getInstance(username_regex), "bad_username");
val.add("username", MethodRule.getInstance(this, "checkUsernameEdit"), "username_already_exists");
val.add("email", EmailRule.getInstance(), "bad_email");
}
}
boolean checkUsernameAdd(String username) {
return userDAO.findByUsername(username) == null;
}
boolean checkUsernameEdit(String username) {
User currentUser = getSessionObj();
// first check if he is actually changing his username...
if (!currentUser.getUsername().equals(username)) {
return userDAO.findByUsername(username) == null;
}
return true;
}
// (...)
}
上面代码的几个要点:
- “required_field”, “bad_username”, “username_already_exists”, 等,是你在I18N (国际化) 文件查找实际校验错误信息对应的key。如果你不想使用国际化,你可以不使用key,直接使用提示信息。
val.requiredFields("Field is required!", "username", "password", "email", "groupId", "languageId");
val.add("username", RegexRule.getInstance(username_regex), "用户名无效!");
requiredFields 和requiredLists方法使用的变量, 第一个参数就是i18n的key,接下来的参数就是需要校验的字段名称。
如果想更进一步进行校验,例如,你可能需要数据库校验,你可以在action中使用MethodRule来进行。
在JSP上展示校验错误信息
你可以使用条件标签 outError
<%@ page contentType="text/html; charset=UTF-8"%>
<%@taglib prefix="mtw" uri="http://www.mentaframework.org/tags-mtw/"%>
<html>
<body>
<h1>Hello Validation!</h1>
<mtw:form action="User.add.mtw" method="post>
Your username: <mtw:input name="username" size="25" />
<mtw:outError field="username">
<font color="red"><mtw:out /></font>
</mtw:outError>
<br>Your age: <mtw:select name="age" size="1" list="ages">
<mtw:outError field="age">
<font color="red"><mtw:out /></font>
</mtw:outError>
<br>Your password: <mtw:input type="password" name="password" size="25" />
<mtw:outError field="password" >
<font color="red"><mtw:out /></font>
</mtw:outError>
<br>Again please: <mtw:input type="password" name="passconf" size="25" />
<mtw:outError field="passconf">
<font color="red"><mtw:out /></font>
</mtw:outError>
<mtw:submit value="Enviar" action="HelloWorld.mtw" method="post" />
</mtw:form>
</body>
</html>
NOTE: outError 标签是一个条件标签,也就是如果没有错误信息,相应字段也就不会阻塞显示信息。
创建自己的验证规则
Mentawai可以轻松创建你自己的校验规则。比如你可以使用RegexRule 方法:
package org.mentawai.rule;
import java.util.HashMap;
import java.util.Map;
/**
* A validation rule applied with a regular expression pattern.
*
* @author Sergio Oliveira
*/
public class RegexRule extends BasicRule {
private final static Map<String, RegexRule> cache = new HashMap<String, RegexRule>();
private String pattern;
/**
* Creates a RegexRule with the given regex pattern.
*
* @param pattern The regex pattern.
*/
public RegexRule(String pattern) {
this.pattern = pattern;
}
public Map<String, String> getTokens() {
return null;
}
public boolean check(String value) {
if (!value.matches(pattern)) return false;
return true;
}
}
在验证错误信息中使用占位符:
getTokens() 方法可以替换占位符。例如,IntegerRule 会返回最大值和最小值,你可以构建如下验证信息。
val.add("age", IntegerRule.getInstance(18, 99), "Age must be between %min% and %max%!");
手动添加错误信息
// 继承BaseAction的任意action中任意位置
addError("无效用户名", "username");
// OR
addError("该用户名已经注册!", "username");