`
wangcheng
  • 浏览: 1453741 次
  • 性别: Icon_minigender_1
  • 来自: 青岛人在北京
社区版块
存档分类
最新评论

POJO加Annotation做validation验证

    博客分类:
  • java
阅读更多

写了一个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上。主要原因是

  • 这样不会破坏java的public, private等访问限制。
  • 加在get方法上更加灵活,你可以验证由几个filed组合而成的一个String是否符合条件

 

再说一下实现,其实很简单, 像下面这样创建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提交,有什么不足的还请大家指点。

 

分享到:
评论
4 楼 neptune 2008-08-28  
我也和你做了一个一样的东西,给你提点见意.
1.把你的Validator Annotation改为metadata Annotation对扩展最好。
2.required不应做为annotation。其注释在pojo中的某个field没有意义。
3 楼 stworthy 2008-08-27  
这只能在WEB环境中进行,脱离WEB就只能得到key而得不到具体的message了。
2 楼 wangcheng 2008-08-27  
可以在annotation的messageKey里写i18n的message key,
验证完后,得到了error message 的 i18n key 就随你怎么处理了。
用JSTL也行,在Action里处理也行。
1 楼 stworthy 2008-08-27  
请问这样的国际化如何解决?

相关推荐

    annotation.jar eclipse插件,根据数据库自动生成pojo

    annotation.jar eclipse插件,根据数据库自动生成pojo

    POJO In action 代码

    POJO In action 代码 POJO In action 代码 POJO In action 代码

    POJO转Map.txt

    POJO转Map代码,POJO转Map代码POJO转Map代码POJO转Map代码

    SSM笔记-POJO

    SSM笔记-POJO,测试POJO,SpringMVC会根据请求参数名和POJO类的属性名自动匹配为对应对象填充值

    netty pojo 文档

    netty pojo netty pojo替换 channelbuffer

    Mybatis生成pojo插件

    Mybatis pojo插件生成工具 把包下载下来,配置到eclipse中,project new 可以看到mybatis插件已经安装好

    POJO javaBean EJB JNDI 理解及区别

    POJO javaBean EJB JNDI 理解及区别

    json2pojo功能有点麻烦

    参照https://github.com/joelittlejohn/jsonschema2pojo/wiki/Getting-Started的步骤Using jsonschema2pojo within your Java project (embedded)

    简单数据库逆向工程 自动生成POJO类

    1.1.1版本 简单数据库逆向工程 自动生成POJO类 JAVA WEB jsp

    java反射封装结果集内容到pojo

    当我们从数据库读出数据得到ResultSet... 这里面还有一段代码,是把数据库结果集封装到Map代替pojo,有些人也许认为不符合OO思想,但是这还没有成为一个定论,而且Map和List,在迭代时的效率非常高,我认为值得这样去做

    hibernate生成pojo

    hibernate生成pojo

    SSM项目实战pojo类

    本资源为博客中ssm项目实战第二天需要用到的pojo类的压缩包,包含该项目所有的pojo类

    POJO Class

    This is a easy POJO class!

    IDEA逆向生成POJO/DAO/MAPPER 《Generate POJOs.groovy》

    IDEA自带的插件Generate POJOs.groovy 比较简陋,不能生成完整的dao/mapper,切生成的POJO没有注解。没有统一格式化,所以在此基础上进行了扩展能够简单的生成pojo/dao/mapper. 使用时选择目录后会在改目录下生成...

    POJO代码生成器 Swing做的

    超级简单好用的代码生成器,解压后先看看readme 运行时,填入列名和java中的属性类型后点击生成, 就可以生成一个pojo.java文件,不需要手写了 原理也很简单,作为想复习j2se知识的同学来说也很实用哦!

    数据表生成pojo

    保存资源,以后开发备用,数据表生成pojo,java代码。

    java Pojo转Map

    jsp上使用object[]看不懂吧?写vo太烦琐了?ok,都交给map吧、本工具类的使命就是让map代替所有的vo,让编程变得更美好。 附有详细的使用例子。 java精英团队十年编程精华。

    超级POJO程序设计方言.rar

    超级POJO程序设计方言.rar超级POJO程序设计方言.rar超级POJO程序设计方言.rar超级POJO程序设计方言.rar超级POJO程序设计方言.rar超级POJO程序设计方言.rar超级POJO程序设计方言.rar超级POJO程序设计方言.rar超级POJO...

    利用Mybatis逆向工程来生成pojo和mapper

    利用Mybatis逆向工程来生成pojo,dao和mapper。然后将pojo实体类和dao拷贝到工程当中。这样可以快速地实现数据库的开发

    pojo类与javaBean

    文档主要介绍pojo与javaBean的区别

Global site tag (gtag.js) - Google Analytics