【狂人小白】輕量級驗證框架 Validation.FO 的入門與使用

Validation.FO 使用指南

框架說明

  1. 這是一個驗證框架,並且是一個 獨立的驗證框架 ,不依賴與其他已有的框架;

  2. 可以自由的嵌入到其他框架,比如Spring、Struts等流行框架,但實質來說他是獨立的,所以無所謂嵌入到哪裏,如果需要在GUI桌面應用中,也是完美的;

  3. 配置簡單,可自由擴展驗證器,實際只要實現IValidator接口,以及在rules.fo.xml中添加相關的配置即可;

  4. 支持Spring接口

  5. 使用過程中,你會感覺好像只用了 IValidateService.validate() 一個方法,這會讓人感覺良好

優點

  1. 不與任何對象做綁定,最大限度解耦

  2. 只要規則配置寫的合理,規則可以複用到多個對象

  3. 擴展驗證器很簡單

  4. 以Map存儲驗證結果,非常簡單的導出JSON,只要你願意

相關文檔

如何下載

<dependency>
	<groupId>cc.fozone.validation</groupId>
	<artifactId>fo-validation</artifactId>
	<version>0.9.1.RELEASE</version>
</dependency>

快速開始

使用Validation.FO的步驟如下:

  1. 配置驗證規則 rules.fo.xml

  2. 實例化 IValidateService 對象

  3. 調用 IValidateService.validate 方法

基本的使用方法

源代碼地址:Basic Usage

1. 創建POJO對象 User.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

  • <include file=""/>
    導入其他規則文件

  • <group name=""></group>
    驗證分組,name應該爲全局唯一的

  • <field name=""></field>
    驗證的字段,name是被驗證對象的屬性字段名

  • <rule name="" message=""></rule>
    驗證規則,name是驗證器名稱,message是錯誤後返回的消息

  • <param name="" value=""></param>
    是驗證規則時可能需要傳入的參數,name是參數名,value是參數值

<?xml version="1.0" encoding="UTF-8"?>
<fozone-validation>
	<!-- include 標籤導入其他配置 -->
	<include file="validationinfo/basic/another-rules.fo.xml"/>
	 
	<!-- 驗證組ID,全局唯一 -->
	<group name="user.validate">
		<!-- 驗證字段 -->
		<field name="email">
			<!-- 
				規則列表
			-->
			<rule name="required" message="郵件必須填寫"/>
		<rule name="between" message="郵件長度應該3-100之間">
			<param name="min" value="3"/>
			<param name="max" value="100"/>
		</rule>
			<rule name="match" message="郵件格式不正確">
				<param name="regex" value="^[A-Za-z]+[\.\-_A-Za-z0-9]*@[A-Za-z0-9]+[\.\-_A-Za-z0-9]*$"/>
			</rule>
		</field>

		...

	</group>
</fozone-validation>

3. 實例化測試 BasicTest.java

主要步驟:

  1. 創建配置讀取對象IValidateConfig

  2. 創建驗證服務對象IValidateService

  3. 執行驗證方法IValidateService.validate(object, groupId)

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<String,String> map = validateService.validate(user, "user.validate");
		// 輸出結果
		if(map == null || map.size() == 0) {
			System.out.println("驗證成功");
		} else {
			System.out.println("驗證失敗,結果如下");
			System.out.println(map);
		}
	}
}

4. 結果輸出

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 源代碼下載

1. 配置Spring配置 context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

	<!-- 基於 Spring 配置讀取 -->
	<bean id="springValidateConfig" class="cc.fozone.validation.config.SpringValidateConfig">
		<property name="validators">
			<value>validationfo/spring/validators.fo.xml</value>
		</property>
		<property name="rules">
			<value>validationfo/spring/rules.fo.xml</value>
		</property>
	</bean>
	
	<!-- 配置驗證服務 -->
	<bean id="basicValidateService" class="cc.fozone.validation.BasicValidateService">
		<constructor-arg index="0" ref="springValidateConfig"/>
	</bean>
	
	<!-- 配置基於Spring的驗證器 -->
	<bean class="cc.fozone.validation.validators.SpringValidator"/>
</beans>

2. 如何通過Spring進行驗證,SpringTest.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<String, String> map = service.validate(user, "user.validate");
		// 輸出結果
		if (map == null || map.size() == 0) {
			System.out.println("驗證成功");
		} else {
			System.out.println("驗證失敗,結果如下");
			System.out.println(map);
		}
	}
}

3. 執行結果

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 version="1.0" encoding="UTF-8"?>
<fozone-validators>
	<validator name="required" class="cc.fozone.validation.validators.RequiredValidator"/>
	<validator name="match" class="cc.fozone.validation.validators.MatchValidator"/>
	<validator name="between" class="cc.fozone.validation.validators.BetweenValidator"/>
	<validator name="min" class="cc.fozone.validation.validators.MinValidator"/>
	<validator name="max" class="cc.fozone.validation.validators.MaxValidator"/>
	<validator name="equals" class="cc.fozone.validation.validators.EqualsValidator"/>
	<validator name="timestampLessEqual" class="cc.fozone.validation.validators.TimestampLessEqualValidator"/>
	<validator name="timestampCreaterEqual" class="cc.fozone.validation.validators.TimestampCreaterEqualValidator"/>
	<validator name="spring"  useSpring="true" class="cc.fozone.validation.validators.SpringValidator"/>
</fozone-validators>

默認驗證規則

required - 必填字段

消息message: 必填

參數param: 無

案例:

<group name="user.validate">
	<field name="username">
		<rule name="required" message="姓名必須填寫。"/>
	</field>
</group>

match - 正則匹配

消息message: 必填

參數param:

NameMustDescription
regexYes正則表達式,如果爲空,驗證直接返回true

案例:

<group name="user.validate">
	<field name="email">
		<rule name="match" message="郵件格式不正確">
			<param name="regex" value="^[A-Za-z]+[\.\-_A-Za-z0-9]*@[A-Za-z0-9]+[\.\-_A-Za-z0-9]*$"/>
		</rule>
	</field>
</group>

between - 判斷字符串或數組非空長度是否介於兩者之間,min <= length <= max

消息message: 必填

參數param:

NameMustDescription
minYes最小長度(包含)
maxYes最大長度(包含)

案例:

<group name="user.validate">
	<field name="email">
		<rule name="between" message="郵件長度應該3-100之間">
			<param name="min" value="3"/>
			<param name="max" value="100"/>
		</rule>
	</field>
</group>

min - 判斷字符串或數組非空長度是否大於等於最小長度,length >= min

消息message: 必填

參數param:

NameMustDescription
valueYes最小長度(包含)

案例:

<group name="user.validate">
	<field name="password">
		<rule name="min" message="密碼至少5個字符">
			<param name="value" value="5"/>
		</rule>
	</field>
</group>

max - 判斷字符串或數組非空長度是否小於等於最大長度,length <= max

消息message: 必填

參數param:

NameMustDescription
valueYes最大長度(包含)

案例:

<group name="user.validate">
	<field name="password">
		<rule name="max" message="密碼最多20個字符">
			<param name="value" value="20"/>
		</rule>
	</field>
</group>

equals - 判斷字段是否與指定的字段值是否相同

消息message: 必填

參數param:

NameMustDescription
targetYes指定的字段名稱,並非確定的值

案例:

POJO對象部分字段

public class User {
	private String password;
	private String passwordOne;
}
<group name="user.validate">
	<field name="password">
		<rule name="equals" message="兩次輸入的密碼不相同">
			<param name="target" value="passwordOne"/>
		</rule>
	</field>
</group>

注:這裏會將password與目標passwordOne字段的值進行equals比較
有些時候你可能需要重寫equals方法


timestampLessEqual - 時間戳是否小於等於指定的目標時間字段

消息message: 必填

參數param:

NameMustDescription
targetYes指定的時間字段名稱,並非確定的值

案例:

POJO對象部分字段

public class User {
	private Timestamp starttime;
	private Timestamp endtime;
}
<group name="user.validate">
	<field name="starttime">
		<rule name="timestampLessEqual" message="開始時間不能大於結束時間">
			<param name="target" value="endtime"/>
		</rule>
	</field>
</group>

注:

  1. 這裏會將starttime與目標endtime字段的值進行大小比較

  2. 這裏的字段必須是java.sql.Timestamp類型


timestampCreaterEqual - 時間戳是否大於等於指定的目標時間字段

消息message: 必填

參數param:

NameMustDescription
targetYes指定的時間字段名稱,並非確定的值

案例:

POJO對象部分字段

public class User {
	private Timestamp starttime;
	private Timestamp endtime;
}
<group name="user.validate">
	<field name="endtime">
		<rule name="timestampCreaterEqual" message="結束時間不能小於開始時間">
			<param name="target" value="starttime"/>
		</rule>
	</field>
</group>

注:

  1. 這裏會將endtime與目標starttime字段的值進行大小比較

  2. 這裏的字段必須是java.sql.Timestamp類型


spring - 通過Spring調用其他對象的指定方法進行判斷

DEMO: 點擊查看

消息message: 必填

參數param:

NameMustDescription
beanNameYesSpring Context中的Bean標識
methodNameYesBean對象中的指定執行方法,該方法必須返回 boolean 類型
parameterNameNo執行方法中傳遞的參數,**默認** 傳遞被驗證字段的值,如果使用**this** 表示傳遞被驗證的對象, 其他 表示傳遞對象指定的字段

案例:

POJO對象部分字段

public class User {
	private String username;
	private int usernameLength;
}

驗證配置

<group name="user.validate">
	<field name="username">
		<rule name="spring" message="該用戶已存在">
			<param name="beanName" value="userService"/>
			<param name="methodName" value="exist"/>
		</rule>
	</field>
	
	<field name="usernameLength">
		<!-- 使用 this 關鍵字 -->
		<rule name="spring" message="用戶名長度驗證錯誤">
			<param name="beanName" value="userService"/>
			<param name="methodName" value="length"/>
			<param name="parameter" value="this"/>
		</rule>
		
		<!-- 指定字段 -->
		<rule name="spring" message="用戶名長度不能小於5個字符">
			<param name="beanName" value="userService"/>
			<param name="methodName" value="lengthByName"/>
			<param name="parameter" value="username"/>
		</rule>
	</field>
</group>

Spring中的配置

<beans>
	<!-- 通過Spring進行驗證 -->
	<bean id="userService" class="validationfo.springadvance.UserService"/>
</beans>

通過Spring驗證的接口

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源代碼

一個簡單的例子

POJO對象

package validationfo.custom;

public class Money {
	private int number;
	private String text;
	
	...
	
}

CustomValidator實現

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配置的參數說明

語法<validator name="" useSpring="true|false"  class=""  beanId=""/>

參數名必填含義
name驗證器名稱
useSpring是否通過 Spring 實例化驗證器,這樣做可以爲驗證器注入 ApplicationContext
classuseSpring=false 時,按照正常的方式進行實例化;當 useSpring=true 時,且使用了 beanId ,則 class 無效,如果沒有使用 beanId ,那麼 Spring 通過 class 進行實例化
beanIdSpring中的bean id
<?xml version="1.0" encoding="UTF-8"?>
<fozone-validators>
	...
	<validator name="custom" class="validationfo.custom.CustomValidator"/>
</fozone-validators>

配置驗證規則

<?xml version="1.0" encoding="UTF-8"?>
<fozone-validation>
	<!-- 驗證組ID,全局唯一 -->
	<group name="money.validate">
		<!-- 驗證字段 -->
		<field name="number">
			<rule name="custom" message="驗證失敗,不能被指定的數整除">
				<param name="value" value="3"/>
			</rule>
		</field>
	</group>
</fozone-validation>

執行測試

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<String,String> map = validateService.validate(money, "money.validate");
		// 輸出結果
		if(map == null || map.size() == 0) {
			System.out.println("驗證成功");
		} else {
			System.out.println("驗證失敗,結果如下");
			System.out.println(map);
		}
	}	
}

結果輸出

16:44:17,178  INFO BasicValidateConfig:44 - read validation main file , validationfo/custom/rules.fo.xml
TEXT = 演示Context使用的Text
驗證失敗,結果如下
{number=驗證失敗,不能被指定的數整除}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章