With Mentawai you can perform validation inside the action using the Validatable interface or you can create a separate filter just for that. The first method is preferred. Here is an example:
Setting up the filter in the application manager:
@Override public void loadFilters() { filter(new ValidationFilter()); }
Performing the validation in the 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; } // (...) }
Important points about the above code:
val.requiredFields("Field is required!", "username", "password", "email", "groupId", "languageId"); val.add("username", RegexRule.getInstance(username_regex), "The username is invalid!");
Displaying validation error messages in the JSP:
You can use the conditional tag outError as below:
<%@ 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: The outError menta tag is a conditional tag, in other words, if there is no error message for the field nothing in the tag block will be displayed.
Creating your own validation rules:
Mentawai makes it easy to create your own validation rules. You can take the RegexRule as an example:
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; } }
Using placeholders in the validation error messages:
The method getTokens() can be overriden to return some placeholders. For example, the IntegerRule returns the values min and max as placeholders so you can construct your validation messages like that:
val.add("age", IntegerRule.getInstance(18, 99), "Age must be between %min% and %max%!"); // using placeholders
Adding error messages by hand:
// anywhere inside your action (that extends BaseAction) addError("bad_username", "username"); // username is the field the error message relates to // OR addError("This username is already taken!", "username");