`
hellohank
  • 浏览: 143886 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

基于java反射的验证框架

阅读更多

写在前面

相信很多经历了项目的人,会发现几乎没有哪个项目不需要验证的。在经历过多个项目之后,有感于项目中使用最多的验证方式,这里写了一个基于java反射机制的验证框架。该框架适用于对javaBean中的属性通过java反射机制获取对应的值和用户直接传入的值来进行各种规则的验证。由于其几乎不依赖任何第三方jar包,因此可以适用所有java项目中。

开始使用


1、由于这些代码是在JDK1.5环境下编写的,用到了JDK1.5中的一些高级特性(如泛型等),因此使用该框架的项目最好是基于JDK1.5及以上版本的。
2、使用方式。
在这个框架中,整个使用的入口就是一个工具类:com.cloudframework.validation.ValidatorUtils。具体使用示例如下(示例代码在com.cloudframework.validation.sample.Demo):

DemoEntity de = new DemoEntity();//DemoEntity是一个javaBean。
  // 普通使用
  CloudBindingResult result = ValidatorUtils.validateEntity(de, "str", NotEmptyRule.class);
  System.out.println(result.getFieldErrorMessage("str"));
  // 自定义验证信息
  result = ValidatorUtils.validateEntity(de, "str", new NotEmptyRule("这里是指定验证信息示范!"));
  System.out.println(result.getFieldErrorMessage("str"));
  // 同时验证两个属性
  result = ValidatorUtils.validateEntity(de, "num,date", NotNullRule.class);
  System.out.println(result.getFieldErrorMessage("num") + " || " + result.getFieldErrorMessage("date"));
  // 使用多个验证规则
  result = ValidatorUtils.validateEntity(de, "str", NotEmptyRule.class, SingleEmailRule.class);
  System.out.println(result.getFieldErrorMessage("str"));// 这里注意其打印出来的验证信息!
  // 多个属性同时使用多个规则
  result = ValidatorUtils.validateEntity(de, "str,col", NotEmptyRule.class, SingleEmailRule.class);
  System.out.println(result.getFieldErrorMessage("str") + " || " + result.getFieldErrorMessage("col"));

 
其运行结果为:

不能为空!
这里是指定验证信息示范!
不能为空! || 不能为空!
不能为空!;邮箱格式不正确!
不能为空!;邮箱格式不正确! || 不能为空!;邮箱格式不正确!

 
3、 需要注意的是,有时候,我们需要验证一个单独的字符串或数字是否符合某个规则,这时候,这样的值并不是javaBean中的值,在这样的情况下,ValidatorUtils中的validateValue方法正是解决这样的单独验证的,它是可以直接验证给定的内容的。示例如下:

// 注意下面方法的返回值,是String类型。
System.out.println(ValidatorUtils.validateValue("hello",NotEmptyRule.class,SingleEmail.class)); 
System.out.println(ValidatorUtils.validateValue("",NotEmptyRule.class,SingleEmail.class)); 
System.out.println(ValidatorUtils.validateValue(null,NotEmptyRule.class,SingleEmail.class)); 
System.out.println(ValidatorUtils.validateValue("hello",NotEmptyRule.class));

 
其运行结果如下:

邮箱格式不正确!
不能为空!;邮箱格式不正确!
不能为空!;邮箱格式不正确!

 

自定义规则


在上面的使用中,我们用到了这些规则:NotEmptyRule、NotNullRule、SingleEmailRule。这些规则是我已经在框架中提供的仅有的三种规则!对于业务复杂、规则众多的情况下,用户可以自己扩展这些规则。扩展的方式为:新建一个类,并实现自com.cloudframework.validation.rules.ValidateRule接口。该接口代码如下:

package com.cloudframework.validation.rules;

/**
 * 验证规则的接口。所有的具体验证规则都实现自这个接口。
 * 
 * @author taofucheng
 * 
 */
public interface ValidateRule {
 /**
  * 进行具体规则的验证逻辑。
  * 
  * @param value
  *            具体的验证内容。
  * @return true:验证通过;false:验证不通过
  */
 public boolean validate(Object value);

 /**
  * 获取验证不通过时的报错信息。如果用户指定的验证信息为空,则返回默认的报错信息。
  * 
  * @return 返回验证的报错信息
  */
 public String getValidateInfo();
}

 
具体实现和规则的使用的示例可以参考现有的这三个规则类(NotEmptyRule、NotNullRule、SingleEmailRule)。

设计


在整个框架的设计中,其设计思路很简单:调用入口到反射取值,调用规则验证。其UML图可示例如下(使用StarUML作图):
UML图

设计思想与各关系上图中已经详细表明了,这里就不赘述了。

后记


现有的不足


字段名称不宜控制。现在的使用方式为:ValidatorUtils.validateEntity(entity, "field1", NotEmptyRule.class),其中字段名称是用户传入的字符串,如果该实体中的字符串名称发生改变,则这里是无法知晓的!也就是说,这里会因为实体中的字段名称变化而形成一个极隐蔽的隐患!


可扩展为注解

在现在这个年头,注解(annotation)似乎已经很被大众接受,同时也流行开了,从Spring到Hibernate,再到Struts……
在注解风靡的现在,如果这个验证框架没有注解使用方式估计会少了一席战场吧。由于本人急于使用,再加上最近也一直很忙,静不下心来完善,所以上面提到的注解功能就一直没写。其实,注解的实现很简单,建议大家可以参考一下Hibernate validator框架,我觉得这个验证框架很不错,它是完全基于注解的。我也会在后面的某一天将注解的内容补充完整。

补充


1、 对于验证中的字段名称随实体改变而不会留下隐患,我一直找不到一个好的办法解决。想想除了用注解的方式,还真没找到一个合适的方式。
2、 对于注解的使用,我个人认为对于代码的侵入性比较强。我想这也许就是为什么很多人对注解有一定的抵触情绪吧。
3、 这个验证框架,只是依赖于commons-lang.jar包,但只用到了其中的StringUtils类,如果将该类中用到的功能自己实现的话,可以不依赖于任何jar包了!

  • 大小: 85.8 KB
2
1
分享到:
评论
4 楼 zhoupan301415 2017-09-04  
写的非常不错,虽然代码量,但是考虑的还是很周全的,灵活性,扩展性,对于设计模式和反射的理解都很到位,10年能有这般水平,发展到现在,应该也是很厉害的人物了吧,加油!!!
3 楼 hellohank 2010-11-22  
cd_huangbo 写道
可以再结合权限来实现吗?

我觉得,证是对数据规则的验证,而权限是对请求/操作的验证。这是两种不同的验证,不需要结合吧,一旦结合会失去它们的灵活性,呵呵。
2 楼 cd_huangbo 2010-11-19  
可以再结合权限来实现吗?
1 楼 hellohank 2010-11-19  
不管是好是坏,大家给点意见啊~~

相关推荐

    一个既简单的校验框架

    主要的技术上使用了注解, 然后通过反射再利用注解解析器来进行解析进行校验 校验器每个方法返回this,可以使用更优雅的代码来完成校验 并且还可以比较方便的扩展。

    利用java反射校验struts中的form(含正则表达式)

    在struts框架中,如果每次都去校验form中的每个字段,显然费时费力,本例通过java反射得到form中的字段和值,并较验,用于在与数据库交互之前的校验,从而防止数据库恶意注入. 随包附带一个通用的易扩展的正则表达式校验类...

    JAVA_API1.6文档(中文)

    java.lang.reflect 提供类和接口,以获得关于类和对象的反射信息。 java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java....

    Java 1.6 API 中文 New

    java.lang.reflect 提供类和接口,以获得关于类和对象的反射信息。 java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java.nio ...

    yavi:Java 的另一种验证(基于 lambda 的类型安全验证框架)

    YAVI(发音为 jɑ-vάɪ)是一种基于 lambda 的 Java 类型安全验证。 为什么是雅维? YAVI 听起来与日语俚语“YABAI (ヤバイ)”相同,根据上下文意思是很棒或很糟糕(如“疯狂”)。 如果您使用YAVI,您一定会明白...

    JAVA高并发高性能高可用高扩展架构视频教程

    Java-Base64算法_创新_防止表单重复提交 JAVA企业级基础课题(HashMap那些事) ...Java企业级框架之核心技术(反射) Java-Base64算法(创新_防止表单重复提交) 揭开springAOP神秘面纱之动态代理 网络爬虫之JAVA正则表达式

    java api最新7.0

    java.lang.reflect 提供类和接口,以获得关于类和对象的反射信息。 java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java.nio ...

    JavaAPI1.6中文chm文档 part1

    java.lang.reflect 提供类和接口,以获得关于类和对象的反射信息。 java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java....

    JavaAPI中文chm文档 part2

    java.lang.reflect 提供类和接口,以获得关于类和对象的反射信息。 java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java....

    Android集成主流优秀第三方组件框架

    读取本地资源工具类(ToolResource.java),反射本地资源文件API,避免依赖R文件,方便 jar形式发布 Android单位转换工具类(ToolUnit.java),sp/dp/px互转 自定义Toast工具类(ToolToast.java),自定义背景色、字体...

    java jdk-api-1.6 中文 chmd

    java.lang.reflect 提供类和接口,以获得关于类和对象的反射信息。 java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java....

    达内java培训目录

    JavaSE核心 异常处理、多线程基础、IO系统、网络编程、Java反射机制、JVM性能调优(JVM内存结构剖析、GC分析及调优、JVM内存参数优化)、Java泛型、JDK新特性 熟练掌握JavaSE核心内容,特别是IO和多线程;...

    最快的反射工具类

    使用的cglib+缓存 1千万次空方法调用 大概3秒~ 直接反射的速度为10秒~ 缓存后反射为 6秒~ 取出安全验证缓存后的速度为 4秒左右~ 另外大概有2秒的性能消耗在字符串拼接缓存中的key造成~ 因此上面带缓存的反射方案...

    java jdk实列宝典 光盘源代码

    12反射 是java程序开发的特征之一,允许java程序对自身进行检查,并能直接操作程序的内部属性; instanceof操作符,instanceof.java; 获取类的信息,ViewClassInfoJrame.java; 动态调用类的方法,CallMetod.java; ...

    SparkWeb:SparkWeb是一个超轻量级的Java Web MVC框架

    Sparkweb 是一个超轻量级的简易高效的 Java WEB 开发框架,其设计思想结合了目前主流的 Spring、Struts2、Playframework、Nodejs-Expressjs、Ruby On Rails 等框架的优秀地方,完美支持 RESTful设计。 二、Sparkweb ...

    [Java参考文档]

    java.lang.reflect 提供类和接口,以获得关于类和对象的反射信息。 java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java....

    java基础案例与开发详解案例源码全

    15.2 使用Java反射机制414 15.2.1 获取类型信息414 15.2.2 创建对象417 15.2.3 调用方法419 15.2.4 访问成员变量的值421 15.2.5 操作数组422 15.3 反射与动态代理424 15.3.1 静态代理424 15.3.2 动态代理426 15.4 本...

Global site tag (gtag.js) - Google Analytics