浏览 3781 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-08-27
写了一个POJO + Annotation来做validation的验证方案。思路就是在POJO里加入Annotation来标注验证条件,以取代validation.xml等验证方式。
先看一下最终的应用效果
public class UserBean { private String userName; private String password; private String email; @SRequired(messageKey = "Name is required.") public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } @SRequired(messageKey = "Password is required.") @SLength(min = 6, max = 20, messageKey = "Password is 6 - 20") public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @SRegularEx(regex = RegPatterns.EMAIL, messageKey = "Please input a valid email.") public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
public class ValidateTest { public static void main(String[] args) { UserBean user = new UserBean(); List<String> messageList = ValidationUtils.validate(user); for (String s : messageList) { System.out.println(s); } } }
这里只需要在POJO的get方法上加annotation说明验证条件,以及验证失败后的消息(或消息的i18n key)即可,ValidationUtils将收集验证失败的消息并返回。
推荐将annotation加在public getXXX方法上,而不是加在field上。主要原因是
再说一下实现,其实很简单, 像下面这样创建validation annotation
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.METHOD}) public @interface SLength { String messageKey() default ""; int max() default 255; int min() default 0; }
这里SLength的默认范围是 0-255 基本符合大部分项目的需求。
在ValidationUtils中先找出POJO的所有method,然后遍历,取得一个method的返回值,再取出这个method上的所有annotation,遍历这些annotation并找出那些是我们定义的validation annotation,再根据不同的条件分别进行验证。
private static void validateMethods(Object bean, List<String> messageList) { //get all of public methods Method[] publicMethods = bean.getClass().getMethods(); for (Method method : publicMethods) { //ignore if it is not getXXX method if (!isGetterMethod(method)) { continue; } Object value = null; try { value = method.invoke(bean, null); } catch (Exception e) { e.printStackTrace(); } //Annotation[] annotations = method.getDeclaredAnnotations(); Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { validateAnnotation(value, annotation, messageList); } } }
private static void validateAnnotation(Object value, Annotation annotation, List<String> messageList) { if (annotation instanceof SRequired) { validateRequired(value, (SRequired) annotation, messageList); } else if (annotation instanceof SLength) { validateLength(value, (SLength) annotation, messageList); } else if (annotation instanceof SRegularEx) { validateRegularEx(value, (SRegularEx) annotation, messageList); } }
在这里大部分的验证都可以通过 SRegularEx annotation 来做,你只需要自行扩展 RegPatterns 类中定义的正则表达式就行了。有特殊需要的话,你可以创建自己的validation annotation,并扩展ValidationUtils.validateAnnotation()方法。
做这个的时候,只是为了验证web form提交,有什么不足的还请大家指点。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-08-27
请问这样的国际化如何解决?
|
|
返回顶楼 | |
发表时间:2008-08-27
可以在annotation的messageKey里写i18n的message key,
验证完后,得到了error message 的 i18n key 就随你怎么处理了。 用JSTL也行,在Action里处理也行。 |
|
返回顶楼 | |
发表时间:2008-08-27
这只能在WEB环境中进行,脱离WEB就只能得到key而得不到具体的message了。
|
|
返回顶楼 | |
发表时间:2008-08-28
我也和你做了一个一样的东西,给你提点见意.
1.把你的Validator Annotation改为metadata Annotation对扩展最好。 2.required不应做为annotation。其注释在pojo中的某个field没有意义。 |
|
返回顶楼 | |