|
基于范型的java验证框架
经历了很多项目的人,就会发现编写验证代码的过程是多么极其乏味痛苦的历程,而太多的验证代码都极其相似,想尝试用个框架来解决。但在网上搜索一番,发现要么极其复杂不够灵活,要么庞大不适合我的项目。于是发挥劳动人民自力更生的精神,居然被我研究成功了。 二话不说,先上代码。
1.Validate<T1>,这个是主要的框架引擎。
package com.zjg;
import java.io.IOException;
import java.util.ArrayList;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
public class Validate<T1> {
interface IValidateRule<T2> {
public boolean validate(T2 data);
public String getComment();
public String getFailedHint();
public String toJson() throws JsonGenerationException,
JsonMappingException, IOException;
}
public static abstract class BaseValidateRule<T3> implements
Validate.IValidateRule<T3> {
String comment = "";
String failedHint = "";
@Override
public String toJson() throws JsonGenerationException,
JsonMappingException, IOException {
// TODO 自动生成的方法存根
return new UnicodeJsonObjectMapper().writeValueAsString(this);
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
@Override
public String getFailedHint() {
return failedHint;
}
public void setFailedHint(String failedHint) {
this.failedHint = failedHint;
}
}
ArrayList<IValidateRule<T1>> validateRules = new ArrayList<IValidateRule<T1>>();
ArrayList<Boolean> preDependences = new ArrayList<Boolean>();
StringBuffer lastFailedHint = new StringBuffer();
String separator = ",";
String comment = "";
public String toJson() throws JsonGenerationException,
JsonMappingException, JSONException, IOException {
int i = 0;
int size = 0;
JSONStringer stringer = new JSONStringer();
stringer.object();
{
stringer.key("comment").value(comment);
stringer.key("separator").value(separator);
stringer.key("validateRules").array();
{
size = validateRules.size();
for (i = 0; i < size; i++) {
stringer.value(validateRules.get(i).toJson());
}
}
stringer.endArray();
stringer.key("preDependences").array();
{
size = preDependences.size();
for (i = 0; i < size; i++) {
stringer.value(preDependences.get(i));
}
}
stringer.endArray();
stringer.key("validateRuleClassNames").array();
{
size = validateRules.size();
for (i = 0; i < size; i++) {
stringer.value(validateRules.get(i).getClass().getName());
}
}
stringer.endArray();
}
stringer.endObject();
return stringer.toString();
}
public void parseFormJson(String json) throws JsonParseException,
JsonMappingException, IOException, JSONException,
ClassNotFoundException {
JSONObject jsonObject = new JSONObject(json);
comment = jsonObject.getString("comment");
separator = jsonObject.getString("separator");
UnicodeJsonObjectMapper objectMapper = new UnicodeJsonObjectMapper();
ArrayList<IValidateRule<T1>> tmpValidateRules = new ArrayList<IValidateRule<T1>>();
JSONArray validateRulesJsonArray = null;
JSONArray validateRuleClassNamesJsonArray = null;
int i = 0;
int size = 0;
validateRulesJsonArray = jsonObject.getJSONArray("validateRules");
validateRuleClassNamesJsonArray = jsonObject
.getJSONArray("validateRuleClassNames");
size = validateRulesJsonArray.length();
for (i = 0; i < size; i++) {
tmpValidateRules
.add((IValidateRule<T1>) objectMapper.readValue(
validateRulesJsonArray.getString(i), Class
.forName(validateRuleClassNamesJsonArray
.getString(i))));
}
ArrayList<Boolean> tmpPreDependences = new ArrayList<Boolean>();
JSONArray preDependencesJsonArray = jsonObject
.getJSONArray("preDependences");
size = preDependencesJsonArray.length();
for (i = 0; i < size; i++) {
tmpPreDependences.add(preDependencesJsonArray.getBoolean(i));
}
validateRules = tmpValidateRules;
preDependences = tmpPreDependences;
}
public String getLastFailedHint() {
return lastFailedHint.toString();
}
public Validate<T1> addValidateRule(IValidateRule<T1> validateRule,
boolean preDependence) {
if (validateRule == null) {
throw new NullPointerException();
}
validateRules.add(validateRule);
preDependences.add(Boolean.valueOf(preDependence));
String tmpComment = validateRule.getComment();
if (tmpComment.length() > 0) {
if (validateRules.size() > 1) {
comment += ",";
}
comment += tmpComment;
}
return this;
}
public boolean validate(T1 data) {
if (data == null) {
throw new NullPointerException();
}
boolean result = true;
lastFailedHint.setLength(0);
int faliedCount = 0;
String failedHint;
int size = validateRules.size();
for (int i = 0; i < size; i++) {
if (preDependences.get(i) && !result) {
break;
}
if (!validateRules.get(i).validate(data)) {
result = false;
failedHint = validateRules.get(i).getFailedHint();
if (failedHint.length() != 0) {
if (faliedCount > 0) {
lastFailedHint.append(separator);
}
lastFailedHint.append(failedHint);
faliedCount++;
}
}
}
return result;
}
public String getSeparator() {
return separator;
}
public void setSeparator(String separator) {
this.separator = separator;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
2.这是可以无限扩展的规则库
package com.zjg;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ValidateRules {
/**
* Email格式验证
*
* @author 周继光
*
*/
public static class EmailValidateRule extends
Validate.BaseValidateRule<String> {
String regex = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
{
setComment("合法的电子邮件格式");
setFailedHint("非法的电子邮件格式");
}
@Override
public boolean validate(String data) {
// TODO 自动生成的方法存根
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(data);
return matcher.matches();
}
/**
* regex getter
*
* @return regex
*/
public String getRegex() {
return regex;
}
/**
* regex setter
*
* @param regex
* 要设置的 regex
*/
public void setRegex(String regex) {
this.regex = regex;
}
}
public static class MinLengthValidateRule extends
Validate.BaseValidateRule<String> {
int length = 6;
{
setComment("不少于" + length + "(含" + length + ")个字符");
setFailedHint("少于" + length + "个字符");
}
@Override
public boolean validate(String data) {
// TODO 自动生成的方法存根
return data.length() >= length;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
}
public static class MaxLengthValidateRule extends
Validate.BaseValidateRule<String> {
int length = 40;
{
setComment("不多于" + length + "(含" + length + ")个字符");
setFailedHint("多于" + length + "个字符");
}
@Override
public boolean validate(String data) {
// TODO 自动生成的方法存根
return data.length() <= length;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
}
public static class UsernameIllegalCharacterValidateRule extends
Validate.BaseValidateRule<String> {
String regex = "^[\\w\\d\\_\\-\\@\\.]*$";
{
setComment("只能包含\"a-z\",\"A-Z\",\"0–9\",\"_\",\"-\",\"@\",\".\"等字符");
setFailedHint("含有\"a-z\",\"A-Z\",\"0–9\",\"_\",\"-\",\"@\",\".\"之外的字符");
}
@Override
public boolean validate(String data) {
// TODO 自动生成的方法存根
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(data);
return matcher.matches();
}
/**
* regex getter
*
* @return regex
*/
public String getRegex() {
return regex;
}
/**
* regex setter
*
* @param regex
* 要设置的 regex
*/
public void setRegex(String regex) {
this.regex = regex;
}
}
public static class PasswordIllegalCharacterValidateRule extends
Validate.BaseValidateRule<String> {
String regex = "^[\\x21-\\x7e]*$";
{
setComment("只能包含ASCII码表中\"!\"-\"~\"等字符");
setFailedHint("含有ASCII码表中\"!\"-\"~\"之外的字符");
}
@Override
public boolean validate(String data) {
// TODO 自动生成的方法存根
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(data);
return matcher.matches();
}
/**
* regex getter
*
* @return regex
*/
public String getRegex() {
return regex;
}
/**
* regex setter
*
* @param regex
* 要设置的 regex
*/
public void setRegex(String regex) {
this.regex = regex;
}
}
public static class IllegalCharacterValidateRule extends
Validate.BaseValidateRule<String> {
String[] illegalCharacter = { " ", " " };
{
setComment("不能含有\"" + illegalCharacter + "\"等非法字符");
setFailedHint("含有\"" + illegalCharacter + "\"等非法字符");
}
@Override
public boolean validate(String data) {
// TODO 自动生成的方法存根
boolean result = true;
int i = 0;
int size = illegalCharacter.length;
for (i = 0; i < size; i++) {
if (data.indexOf(illegalCharacter) != -1) {
return false;
}
}
return true;
}
/**
* illegalCharacter getter
*
* @return illegalCharacter
*/
public String[] getIllegalCharacter() {
return illegalCharacter;
}
/**
* illegalCharacter setter
*
* @param illegalCharacter
* 要设置的 illegalCharacter
*/
public void setIllegalCharacter(String[] illegalCharacter) {
this.illegalCharacter = illegalCharacter;
}
}
}
3.示例
package com.test;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.json.JSONException;
import com.zjg.Validate;
import com.zjg.ValidateRules;
public class Test {
public static void main(String[] args) {
String username = "BLUE-_baby9811@.163.com";
String password = "BLUE-_baby9811@.163.com!@#$%^&*()_+=-~`:;\"'{[}]|\\<,>.?/";
Validate<String> usernameValidate = new Validate<String>() {
{
setComment("用户名");
}
}.addValidateRule(new ValidateRules.MinLengthValidateRule(), false)
.addValidateRule(new ValidateRules.MaxLengthValidateRule(),
true)
.addValidateRule(
new ValidateRules.UsernameIllegalCharacterValidateRule(),
true);
System.out
.println("validate comment>>" + usernameValidate.getComment());
if (usernameValidate.validate(username)) {
System.out.println("validate hint>>" + "验证成功!");
} else {
System.out.println("validate hint>>"
+ usernameValidate.getLastFailedHint());
}
Validate<String> passwordValidate = new Validate<String>() {
{
setComment("密码");
}
}.addValidateRule(new ValidateRules.MinLengthValidateRule(), false)
.addValidateRule(new ValidateRules.MaxLengthValidateRule(), true)
.addValidateRule(
new ValidateRules.PasswordIllegalCharacterValidateRule(),
true);
System.out
.println("validate comment>>" + passwordValidate.getComment());
if (passwordValidate.validate(password)) {
System.out.println("validate hint>>" + "验证成功!");
} else {
System.out.println("validate hint>>"
+ passwordValidate.getLastFailedHint());
}
//以下代码测试json功能,可以通过json持久化
String tmp = null;
try {
tmp = usernameValidate.toJson();
} catch (JsonGenerationException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (JSONException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println("usernameValidate.toJson()>>" + tmp);
Validate<String> usernameValidate1 = new Validate<String>();
try {
usernameValidate1.parseFormJson(tmp);
} catch (JsonParseException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (JSONException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out
.println("validate comment>>" + usernameValidate1.getComment());
if (usernameValidate1.validate(username)) {
System.out.println("validate hint>>" + "验证成功!");
} else {
System.out.println("validate hint>>"
+ usernameValidate1.getLastFailedHint());
}
}
}
4.结果
validate comment>>用户名不少于6(含6)个字符,不多于40(含40)个字符,只能包含"a-z","A-Z","0–9","_","-","@","."等字符
validate hint>>验证成功!
validate comment>>密码不少于6(含6)个字符,不多于40(含40)个字符,只能包含ASCII码表中"!"-"~"等字符
validate hint>>多于40个字符
usernameValidate.toJson()>>{"comment":"用户名不少于6(含6)个字符,不多于40(含40)个字符,只能包含\"a-z\",\"A-Z\",\"0\u20139\",\"_\",\"-\",\"@\",\".\"等字符","separator":",","validateRules":["{\"length\":6,\"failedHint\":\"\\u5C11\\u4E8E6\\u4E2A\\u5B57\\u7B26\",\"comment\":\"\\u4E0D\\u5C11\\u4E8E6\\uFF08\\u542B6\\uFF09\\u4E2A\\u5B57\\u7B26\"}","{\"length\":40,\"failedHint\":\"\\u591A\\u4E8E40\\u4E2A\\u5B57\\u7B26\",\"comment\":\"\\u4E0D\\u591A\\u4E8E40\\uFF08\\u542B40\\uFF09\\u4E2A\\u5B57\\u7B26\"}","{\"regex\":\"^[\\\\w\\\\d\\\\_\\\\-\\\\@\\\\.]*$\",\"failedHint\":\"\\u542B\\u6709\\\"a-z\\\",\\\"A-Z\\\",\\\"0\\u20139\\\",\\\"_\\\",\\\"-\\\",\\\"@\\\",\\\".\\\"\\u4E4B\\u5916\\u7684\\u5B57\\u7B26\",\"comment\":\"\\u53EA\\u80FD\\u5305\\u542B\\\"a-z\\\",\\\"A-Z\\\",\\\"0\\u20139\\\",\\\"_\\\",\\\"-\\\",\\\"@\\\",\\\".\\\"\\u7B49\\u5B57\\u7B26\"}"],"preDependences":[false,true,true],"validateRuleClassNames":["com.zjg.ValidateRules$MinLengthValidateRule","com.zjg.ValidateRules$MaxLengthValidateRule","com.zjg.ValidateRules$UsernameIllegalCharacterValidateRule"]}
validate comment>>用户名不少于6(含6)个字符,不多于40(含40)个字符,只能包含"a-z","A-Z","0–9","_","-","@","."等字符
validate hint>>验证成功!
5.主要思路
定义一个rule接口,引擎只与接口交互,引擎保存一个rule列表,通过扩展rule接口可以定义很多很多不同的规则,并根据需要添加到引擎的rule列表中对数据一一验证,改变或扩展规则基本不影响用户代码。有一个前置依赖性标志,如果这个标志为true,那么必须通过前面的规则验证,才进行本项规则验证。通过json对持久化支持。
6.后语
还有待完善,希望大家帮忙测试,并多多担宝贵意见,谢谢!
|
|