Here is some code I have been using to do Ruby on Rails-ish style validation in Spring MVC validators
First, clients look like this:
Code:public void validate(Object command, Errors errors) { Job job = (Job) command; ValidationUtil.validatePresenceOf(job, "title", errors); ValidationUtil.validatePresenceOf(job, "jobType", errors); ValidationUtil.validatePresenceOf(job, "description", errors); ValidationUtil.validateLengthOf(job, "title", 3, 100, errors); ValidationUtil.validateLengthOf(job, "employer", 0, 100, errors); ValidationUtil.validateLengthOf(job, "education", 0, 100, errors); ValidationUtil.validateLengthOf(job, "immigrationStatus", 0, 100, errors); ValidationUtil.validateLengthOf(job, "salary", 0, 100, errors); ValidationUtil.validateLengthOf(job, "salaryType", 0, 100, errors); ValidationUtil.validateLengthOf(job, "jobType", 0, 100, errors); ValidationUtil.validateLengthOf(job, "description", 50, 10000, errors); ValidationUtil.validateNumericalityOf(job, "salary", errors); ValidationUtil.validateFormatOf(job, "email", ValidationUtil.REGEX_EMAIL, errors); }messages.propertiesCode:import java.lang.reflect.Method; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.springframework.validation.Errors; /** * Ruby on Rails style validation for Spring MVC applications * * @author John Wheeler */ public class ValidationUtil { public static final String REGEX_EMAIL = "^([^@\\s]+)@((?:[-a-z0-9]+\\.)+[a-z]{2,})$"; private static final String KEY_REQUIRED = "error.required"; private static final String KEY_MIN_LENGTH = "error.minlength"; private static final String KEY_MAX_LENGTH = "error.maxlength"; private static final String KEY_NUMERIC = "error.numeric"; private static final String KEY_FORMAT = "error.format"; private static final String DEFAULT_MSG_REQUIRED = "Value required."; private static final String DEFAULT_MSG_MIN_LENGTH = "Value under minimum length."; private static final String DEFAULT_MSG_MAX_LENGTH = "Value exceeds maximum length."; private static final String DEFAULT_MSG_NUMERIC = "Value must be numeric."; private static final String DEFAULT_MSG_FORMAT = "Value is formatted incorrectly."; /** * Ensures the value of the property specified is not blank or null. */ public static void validatePresenceOf(Object bean, String property, Errors errors) { String value = (String) invokeGetter(bean, property); if (StringUtils.isBlank(value)) { errors.rejectValue(property, KEY_REQUIRED, new String[] { humanize(property) }, DEFAULT_MSG_REQUIRED); } } /** * Ensures the value of the property specified is greater than <code>min</code> and less than * <code>max</code>. */ public static void validateLengthOf(Object bean, String property, int min, int max, Errors errors) { String value = (String) invokeGetter(bean, property); int length = value.length(); if (length < min) { errors.rejectValue(property, KEY_MIN_LENGTH, new String[] { humanize(property), ""+min, ""+length }, DEFAULT_MSG_MIN_LENGTH); } else if (length > max) { errors.rejectValue(property, KEY_MAX_LENGTH, new String[] { humanize(property), ""+max, ""+length }, DEFAULT_MSG_MAX_LENGTH); } } /** * Ensures the value of the property specified is numeric. */ public static void validateNumericalityOf(Object bean, String property, Errors errors) { String value = (String) invokeGetter(bean, property); if ("".equals(value)) return; if (!NumberUtils.isNumber(value)) { errors.rejectValue(property, KEY_NUMERIC, new String[] { humanize(property) }, DEFAULT_MSG_NUMERIC); } } /** * Ensures the value of the property specified matches the given regex. * This class comes with handy constants that start with <code>REGEX_</code> */ public static void validateFormatOf(Object bean, String property, String regex, Errors errors) { String value = ((String) invokeGetter(bean, property)).toLowerCase(); if ("".equals(value)) return; if (!value.matches(regex)) { errors.rejectValue(property, KEY_FORMAT, new String[] { humanize(property) }, DEFAULT_MSG_FORMAT); } } /** * Trys to make a JavaBean property identifier human-readable. * <p> * e.g. <code>immigrationStatus</code> becomes Immigration status * * @param propertyName the property to try and make human-readable * @return the human-readable representation of a JavaBean property identifier */ private static String humanize(String propertyName) { return StringUtils.capitalize(propertyName.replaceAll("([A-Z]{1})", " $1").toLowerCase()); } /** * Invokes a "getter" on the supplied <code>bean</code>. Clients are responsible * for casting the return value. * <p> * e.g. <code>String value = (String) invokeGetter(bean, property);</code> * * @param bean The bean instance to invoke a getter on * @param propertyName The getter's property (don't put 'get' in front of it) * @return the result of the getter */ private static Object invokeGetter(Object bean, String propertyName) { try { String methodName = "get" + StringUtils.capitalize(propertyName); Method method = bean.getClass().getMethod(methodName, new Class[]{}); return method.invoke(bean, new Object[]{}); } catch (Exception e) { throw new RuntimeException(e); } } }
is this pretty good, or is there a better utility?Code:error.required={0} cannot be blank. error.minlength={0} must be at least {1} characters (currently {2} characters). error.maxlength={0} cannot be more than {1} characters (currently {2} characters). error.numeric={0} must be numeric. error.format={0} must be formatted correctly.


Reply With Quote