# Validation.FO **Repository Path**: 41zone/Validation.FO ## Basic Information - **Project Name**: Validation.FO - **Description**: 轻量级验证框架Validation.FO - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 27 - **Forks**: 14 - **Created**: 2014-04-14 - **Last Updated**: 2025-04-20 ## Categories & Tags **Categories**: webframework **Tags**: None ## README ## 框架说明 1. 这是一个验证框架,并且是一个 **独立的验证框架** ,不依赖与其他已有的框架; 2. 可以自由的嵌入到其他框架,比如Spring、Struts等流行框架,但实质来说他是独立的,所以无所谓嵌入到哪里,如果需要在GUI桌面应用中,也是完美的; 3. 配置简单,可自由扩展验证器,实际只要实现IValidator接口,以及在rules.fo.xml中添加相关的配置即可; 4. 支持Spring接口 5. 使用过程中,你会感觉好像只用了 `IValidateService.validate()` 一个方法,这会让人感觉良好 ## 优点 1. 不与任何对象做绑定,最大限度解耦 2. 只要规则配置写的合理,规则可以复用到多个对象 3. 扩展验证器很简单 4. 以Map存储验证结果,非常简单的导出JSON,只要你愿意 ## 如何下载 * Maven依赖 或 直接下载[Validation.FO-0.9.0.RELEASE.jar](https://github.com/41zone/Validation.FO/releases/tag/0.9.0.RELEASE)包 ```Xml cc.fozone.validation fo-validation 0.9.0.RELEASE ``` * 下载配置文件 [Validation.FO-Configuration-0.9.0.zip](https://github.com/41zone/Validation.FO/releases/tag/0.9.0-CONFIGURATION) * DEMO案例源代码,[Validation.FO Demo](https://github.com/jimmy-song/fo-jimmysong-demo/tree/master/src/main/java/validationfo) ## 快速开始 #### 使用Validation.FO的步骤如下: 1. 配置验证规则 `rules.fo.xml` 2. 实例化 `IValidateService` 对象 3. 调用 `IValidateService.validate` 方法 ### 基本的使用方法 源代码地址:[Basic Usage](https://github.com/jimmy-song/fo-jimmysong-demo/tree/master/src/main/java/validationfo/basic) #### 1. 创建POJO对象 `User.java` ```Java package validationfo.basic; import java.sql.Timestamp; /** * 用户对象 * @author Jimmy Song * */ public class User { // 用户名 private String username; // 密码 private String password; // 再次输入密码 private String passwordOne; // 邮箱 private String email; // 开始与结束时间 private Timestamp starttime; private Timestamp endtime; /** * Setter & Getter */ ... } ``` #### 2. 配置验证规则 `rules.fo.xml` * ` ` 导入其他规则文件 * `` 验证分组,name应该为全局唯一的 * `` 验证的字段,name是被验证对象的属性字段名 * `` 验证规则,name是验证器名称,message是错误后返回的消息 * `` 是验证规则时可能需要传入的参数,name是参数名,value是参数值 ```Xml ... ``` #### 3. 实例化测试 `BasicTest.java` **主要步骤:** 1. 创建配置读取对象`IValidateConfig` 2. 创建验证服务对象`IValidateService` 3. 执行验证方法`IValidateService.validate(object, groupId)` ```Java package validationfo.basic; ... /** * 最基本的测试 * @author Jimmy Song * */ public class BasicTest { public static void main(String[] args) { /** * Validation.FO的配置资源 */ // 验证器配置,系统默认配置 String validatorsXML = "validationfo/basic/validators.fo.xml"; // 规则配置 String rulesXML = "validationfo/basic/rules.fo.xml"; /** * 实例化配置对象 */ IValidateConfig config =new BasicValidateConfig(validatorsXML, rulesXML); /** * 实例化验证服务层 */ IValidateService validateService = new BasicValidateService(config); // 实例化用户 User user = createUser(); /** * 执行验证 */ Map map = validateService.validate(user, "user.validate"); // 输出结果 if(map == null || map.size() == 0) { System.out.println("验证成功"); } else { System.out.println("验证失败,结果如下"); System.out.println(map); } } } ``` #### 4. 结果输出 ```Java 12:31:41,084 INFO BasicValidateConfig:44 - read validation main file , validationfo/basic/rules.fo.xml 验证失败,结果如下 {email=邮件格式不正确, password=两次密码输入不正确, starttime=开始时间不能大于结束时间, endtime=结束时间不能小于开始时间} ``` ## 如何在Spring中使用 1. 在Spring中需要使用 `SpringValidateConfg` 配置对象 2. 需要额外配置 `SpringValidator` Bean对象 3. [Spring DEMO 源代码下载](https://github.com/jimmy-song/fo-jimmysong-demo/tree/master/src/main/java/validationfo/spring) #### 1. 配置Spring配置 `context.xml` ```Xml validationfo/spring/validators.fo.xml validationfo/spring/rules.fo.xml ``` #### 2. 如何通过Spring进行验证,`SpringTest.java` ```Java public class SpringTest { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "validationfo/spring/context.xml"); // 获取验证服务 IValidateService service = context.getBean(IValidateService.class); // 创建用户对象 User user = createUser(); // 执行验证 Map map = service.validate(user, "user.validate"); // 输出结果 if (map == null || map.size() == 0) { System.out.println("验证成功"); } else { System.out.println("验证失败,结果如下"); System.out.println(map); } } } ``` #### 3. 执行结果 ```Java 13:26:00,150 INFO ClassPathXmlApplicationContext:510 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@283b4947: startup date [Tue Oct 07 13:26:00 CST 2014]; root of context hierarchy 13:26:00,194 INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [validationfo/spring/context.xml] 13:26:00,373 INFO DefaultListableBeanFactory:598 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@212b0f8a: defining beans [springValidateConfig,basicValidateService,cc.fozone.validation.validators.SpringValidator#0]; root of factory hierarchy 13:26:00,442 INFO BasicValidateConfig:44 - read validation main file , validationfo/spring/rules.fo.xml 验证失败,结果如下 {email=邮件格式不正确, password=两次密码输入不正确, starttime=开始时间不能大于结束时间, endtime=结束时间不能小于开始时间} ``` ## Validator验证器与规则 系统默认的验证器文件 `validators.fo.xml` ```Xml ``` ### 默认验证规则 #### `required` - 必填字段 消息message: **必填** 参数param: 无 案例: ```Xml ``` *** #### `match` - 正则匹配 消息message: **必填** 参数param: **有** |Name|Must|Description| |:--|:--:|:--| |regex|Yes|正则表达式,如果为空,验证直接返回true| 案例: ```Xml ``` *** #### `between` - 判断字符串或数组非空长度是否介于两者之间,min <= length <= max 消息message: **必填** 参数param: **有** |Name|Must|Description| |:--|:--:|:--| |min|Yes|最小长度(包含)| |max|Yes|最大长度(包含)| 案例: ```Xml ``` *** #### `min` - 判断字符串或数组非空长度是否大于等于最小长度,length >= min 消息message: **必填** 参数param: **有** |Name|Must|Description| |:--|:--:|:--| |value|Yes|最小长度(包含)| 案例: ```Xml ``` *** #### `max` - 判断字符串或数组非空长度是否小于等于最大长度,length <= max 消息message: **必填** 参数param: **有** |Name|Must|Description| |:--|:--:|:--| |value|Yes|最大长度(包含)| 案例: ```Xml ``` *** #### `equals` - 判断字段是否与指定的字段值是否相同 消息message: **必填** 参数param: **有** |Name|Must|Description| |:--|:--:|:--| |target|Yes|指定的字段名称,并非确定的值| 案例: POJO对象部分字段 ```Java public class User { private String password; private String passwordOne; } ``` ```Xml ``` > 注:这里会将`password`与目标`passwordOne`字段的值进行`equals`比较 > 有些时候你可能需要重写`equals`方法 *** #### `timestampLessEqual` - 时间戳是否小于等于指定的目标时间字段 消息message: **必填** 参数param: **有** |Name|Must|Description| |:--|:--:|:--| |target|Yes|指定的时间字段名称,并非确定的值| 案例: POJO对象部分字段 ```Java public class User { private Timestamp starttime; private Timestamp endtime; } ``` ```Xml ``` **注:** 1. 这里会将`starttime`与目标`endtime`字段的值进行大小比较 2. 这里的字段必须是`java.sql.Timestamp`类型 *** #### `timestampCreaterEqual` - 时间戳是否大于等于指定的目标时间字段 消息message: **必填** 参数param: **有** |Name|Must|Description| |:--|:--:|:--| |target|Yes|指定的时间字段名称,并非确定的值| 案例: POJO对象部分字段 ```Java public class User { private Timestamp starttime; private Timestamp endtime; } ``` ```Xml ``` **注:** 1. 这里会将`endtime`与目标`starttime`字段的值进行大小比较 2. 这里的字段必须是`java.sql.Timestamp`类型 *** #### `spring` - 通过Spring调用其他对象的指定方法进行判断 DEMO: [点击查看](https://github.com/jimmy-song/fo-jimmysong-demo/tree/master/src/main/java/validationfo/springadvance) 消息message: **必填** 参数param: **有** |Name|Must|Description| |:--|:--:|:--| |beanName|Yes|Spring Context中的Bean标识| |methodName|Yes|Bean对象中的指定执行方法,该方法必须返回 **boolean** 类型| |parameterName|No|执行方法中传递的参数,**默认** 传递被验证字段的值,如果使用**this** 表示传递被验证的对象, **其他** 表示传递对象指定的字段| 案例: **POJO对象部分字段** ```Java public class User { private String username; private int usernameLength; } ``` **验证配置** ```Xml ``` **Spring中的配置** ```Xml ``` **通过Spring验证的接口** ```Java package validationfo.springadvance; public class UserService { public boolean exist(String value) { return !"superman".equals(value); } public boolean length(User user){ return user.getUsername().length() == user.getUsernameLength(); } public boolean lengthByName(String username){ return username.length() >= 5; } } ``` **注:** 1. 要启用spring配置,需要参照上述的 **如何在Spring使用** 进行Spring与Validation.FO的整合配置 2. 指定的对象方法必须返回 **boolean** 类型 ## 高级部分:如何自定义验证器 `IValidator` 1. 实现 `IValidator` 接口 2. 在 `validators.fo.xml` 验证器配置中添加已实现的验证器 3. [点击这里查看Demo源代码](https://github.com/jimmy-song/fo-jimmysong-demo/tree/master/src/main/java/validationfo/custom) ### 一个简单的例子 **POJO对象** ```Java package validationfo.custom; public class Money { private int number; private String text; ... } ``` **CustomValidator实现** ```Java package validationfo.custom; /** * 构造一个判断 参数 是否能够被 指定的值 整出的验证器 * 例如:对象值为4 ,验证参数为2,那么 4可以被2整除,表示成功 * * @author Jimmy Song * */ public class CustomValidator implements IValidator { private static final Logger logger = Logger.getLogger(CustomValidator.class); /** * 要处理的对象 * @param context 上下文 * @param type 对象类型 * @param value 对象值 * @param rule 对象参数 * @return 是否成功 */ public boolean execute(Object context, Class type, Object value, Rule rule) { // TODO Auto-generated method stub /** * 这里只是演示一下context的用处 * 可以通过context以及反射获取对象的属性值 * 举个例子 */ try { System.out.println("TEXT = "+PropertyUtils.getProperty(context, "text")); } catch (Exception e1) { // TODO Auto-generated catch block } /** * 通过 value 实际验证的值 */ if(value == null) return true; /** * 通过 type 获取值的类型 */ if(!(type == Integer.class || type == int.class)) { return false; } int objectValue = ((Integer)value).intValue(); /** * 通过 rule 获取规则参数 */ String toValue = rule.getParameter("value"); if(StringUtils.isBlank(toValue)) return false; int intValue = -1; try { intValue = Integer.parseInt(toValue); } catch(NumberFormatException e){ logger.error("倍数值转换错误!"); return false; } if(intValue <= 0) { logger.warn("倍数值不能小于等于0"); return false; } return objectValue % intValue == 0; } } ``` **配置 validators.fo.xml 中添加自定义验证器** 关于validators.fo.xml配置的参数说明 **语法** : `` |参数名|必填|含义| |:--|:--|:--| |name|是|验证器名称| |useSpring|否|是否通过 **Spring** 实例化验证器,这样做可以为验证器注入 **ApplicationContext** | |class|否|当 **useSpring=false** 时,按照正常的方式进行实例化;当 **useSpring=true** 时,且使用了 **beanId** ,则 **class** 无效,如果没有使用 **beanId** ,那么 **Spring** 通过 **class** 进行实例化| |beanId|否|Spring中的bean id| ```Xml ... ``` **配置验证规则** ```Xml ``` **执行测试** ```Java package validationfo.custom; public class CustomTest { public static void main(String[] args) { /** * Validation.FO的配置资源 */ // 验证器配置,系统默认配置 String validatorsXML = "validationfo/custom/validators.fo.xml"; // 规则配置 String rulesXML = "validationfo/custom/rules.fo.xml"; /** * 实例化配置对象 */ IValidateConfig config =new BasicValidateConfig(validatorsXML, rulesXML); /** * 实例化验证服务层 */ IValidateService validateService = new BasicValidateService(config); // 实例化数据 Money money = new Money(); money.setNumber(7); money.setText("演示Context使用的Text"); /** * 执行验证 */ Map map = validateService.validate(money, "money.validate"); // 输出结果 if(map == null || map.size() == 0) { System.out.println("验证成功"); } else { System.out.println("验证失败,结果如下"); System.out.println(map); } } } ``` **结果输出** ```Java 16:44:17,178 INFO BasicValidateConfig:44 - read validation main file , validationfo/custom/rules.fo.xml TEXT = 演示Context使用的Text 验证失败,结果如下 {number=验证失败,不能被指定的数整除} ```