基于JAVA標(biāo)注實現(xiàn)統(tǒng)一的前臺(JS層)后臺(JAVA層)想法
原創(chuàng),非轉(zhuǎn)
基于JAVA標(biāo)注實現(xiàn)統(tǒng)一的前臺(JS層)后臺(JAVA層)想法[/b]
通過標(biāo)注的方式進行前后臺的統(tǒng)一驗證的好處是很多的,增強前后臺驗證的一致性,減少代碼的重復(fù),不需要前臺與一份驗證,后臺再寫一份了。
本人想基于這種方式寫一個基于Annotation的完整的Validator的開源的小框架,但發(fā)現(xiàn)要做的事情很多,工作量很大,要一點一點的來,一點一點的完善,最后閑時寫了個大 概,與大家一起探討,
以下是Annotation標(biāo)注的代碼。
進行不可以為空的校驗標(biāo)注
進行是否是整數(shù)的校驗標(biāo)注
用于添寫字段中文的標(biāo)注
驗證器的代碼:
下邊是一個加好了標(biāo)注的Student類
在家閑著寫代碼真好。
基于JAVA標(biāo)注實現(xiàn)統(tǒng)一的前臺(JS層)后臺(JAVA層)想法[/b]
通過標(biāo)注的方式進行前后臺的統(tǒng)一驗證的好處是很多的,增強前后臺驗證的一致性,減少代碼的重復(fù),不需要前臺與一份驗證,后臺再寫一份了。
本人想基于這種方式寫一個基于Annotation的完整的Validator的開源的小框架,但發(fā)現(xiàn)要做的事情很多,工作量很大,要一點一點的來,一點一點的完善,最后閑時寫了個大 概,與大家一起探討,
- 通過JAVA標(biāo)注將前臺和后臺的驗證規(guī)則標(biāo)到JAVA的值對象的類中。
- Validator在初始化的過程中,一次性讀入JAVA的值對象的類中驗證規(guī)則的標(biāo)注信息,并生成前臺需要的校驗的JS文件。
- 前臺頁面可以直接引入自動生成的校驗的JS文件,進行校驗。a
- 后臺得到從前臺請求request綁定好值的JAVA的值對象,通過AnnotationValidator類進行驗證。
以下是Annotation標(biāo)注的代碼。
進行不可以為空的校驗標(biāo)注
- @Retention (RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface CanNotNull {
- }
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface IsInteger {
- public int minWidth() default 1;
- public int maxWidth() default Integer.MAX_VALUE;
- public int minValue() default Integer.MIN_VALUE;
- public int maxValue() default Integer.MAX_VALUE;
- }
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface FieldDesc {
- public String value();
- }
驗證器的代碼:
- package com.javaest.validity.process;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import com.javaest.util.StringUtils;
- import com.javaest.validity.annotation.CanNotNull;
- import com.javaest.validity.annotation.FieldDesc;
- import com.javaest.validity.annotation.IsInteger;
- import com.javaest.validity.test.pojo.Student;
- public class PojoBeanAnnotationValiditer {
- private static Map<String, Map> allValidityRuleMap = new HashMap<String, Map>();
- private static Map<String, Map> allFieldDescMap = new HashMap<String, Map>();
- private static String jsValiditerFilePath;
- private static String[] pojoBeanPackageName;
- /**
- *
- 將指定的包下邊的所有Pojo類的標(biāo)注信息一次性的讀取到Map中,以備以后驗證對象時使用
- */
- public static void loadAllClassAnnotationValidityInfoInPackage(String[] packageNameArr)
- throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchMethodException,
- InvocationTargetException, ClassNotFoundException, IOException {
- for (int i = 0; i < packageNameArr.length; i++) {
- List<Class> classList = ReflectUtils.getAllClassInPackage(packageNameArr[i]);
- for (int j = 0; j < classList.size(); j++) {
- Class currClass = classList.get(j);
- String classFullName = currClass.getPackage().getName() + "." + currClass.getName();
- Map[] validityRuleMapAndFieldDescMap = loadValidityRuleAndCreateValidityJsFile(currClass);
- allValidityRuleMap.put(classFullName, validityRuleMapAndFieldDescMap[0]);
- allFieldDescMap.put(classFullName, validityRuleMapAndFieldDescMap[1]);
- }
- }
- }
- /*
- * 對具體的一個類的標(biāo)注做處理,讀入字段描述 信息,讀入非空驗證信息,讀入整數(shù)驗證信息,并根據(jù)這些信息生成JS代碼。
- */
- private static Map[] loadValidityRuleAndCreateValidityJsFile(Class currClass) throws IllegalArgumentException,
- IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException, IOException {
- StringBuffer validityCanNotNullJsStrBuf = new StringBuffer();
- StringBuffer validityIsIntegerJsStrBuf = new StringBuffer();
- Field[] fieldArr = currClass.getDeclaredFields();
- List<String> canNotNullFieldNameList = new ArrayList<String>();
- List<IsIntegerValiditerRuleInfo> isIntegerValiditerRuleInfoList = new ArrayList<IsIntegerValiditerRuleInfo>();
- Map<String, String> fieldDescMap = new HashMap<String, String>();
- for (int i = 0; i < fieldArr.length; i++) {
- String currFieldName = fieldArr[i].getName();
- //讀入字段描述 信息
- FieldDesc fieldDescAnnotation = fieldArr[i].getAnnotation(FieldDesc.class);
- if (fieldDescAnnotation != null) {
- String fieldDesc = fieldDescAnnotation.value();
- System.out.println(fieldDesc);
- fieldDescMap.put(currFieldName, fieldDesc);
- }
- else {
- fieldDescMap.put(currFieldName, currFieldName);
- }
- //讀入非空驗證信息
- if (fieldArr[i].isAnnotationPresent(CanNotNull.class)) {
- canNotNullFieldNameList.add(currFieldName);
- validityCanNotNullJsStrBuf.append("if(document.all." + currFieldName + ".value.trim()==\"\"){alert('"
- + fieldDescMap.get(currFieldName) + "不可以為空');}\n");
- }
- //讀入整數(shù)驗證信息
- IsInteger isIntegerAnnotation = fieldArr[i].getAnnotation(IsInteger.class);
- if (isIntegerAnnotation != null) {
- int minWidth = isIntegerAnnotation.minWidth();
- int maxWidth = isIntegerAnnotation.maxWidth();
- int minValue = isIntegerAnnotation.minValue();
- int maxValue = isIntegerAnnotation.maxValue();
- IsIntegerValiditerRuleInfo isIntegerValiditerRuleInfo = new IsIntegerValiditerRuleInfo(currFieldName,
- minWidth, maxWidth, minValue, maxValue);
- isIntegerValiditerRuleInfoList.add(isIntegerValiditerRuleInfo);
- if (minWidth > 0) {
- validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName
- + ".value.length()<minWidth){alert('" + fieldDescMap.get(currFieldName) + "寬度不夠!');}\n");
- }
- if (maxWidth < Integer.MAX_VALUE) {
- validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName
- + ".value.length()>maxWidth){alert('" + fieldDescMap.get(currFieldName) + "寬度太長!');}\n");
- }
- if (minValue > Integer.MIN_VALUE) {
- validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName + ".value*1<minValue){alert('"
- + fieldDescMap.get(currFieldName) + "的數(shù)值太小!');}\n");
- }
- if (maxValue < Integer.MAX_VALUE) {
- validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName + ".value*1>maxValue){alert('"
- + fieldDescMap.get(currFieldName) + "的數(shù)值太大!');}\n");
- }
- }
- }
- Map<String, List> classValidityRuleMap = new HashMap<String, List>();
- classValidityRuleMap.put("canNotNullFieldNameList", canNotNullFieldNameList);
- classValidityRuleMap.put("isIntegerValiditerRuleInfoList", isIntegerValiditerRuleInfoList);
- //根據(jù)這些信息生成JS代碼
- BufferedWriter jsFileWriter = new BufferedWriter(new FileWriter(new File(jsValiditerFilePath
- + java.io.File.separator + currClass.getName() + ".js")));
- jsFileWriter.write(validityCanNotNullJsStrBuf.toString());
- jsFileWriter.write(validityIsIntegerJsStrBuf.toString());
- jsFileWriter.close();
- return new Map[] { classValidityRuleMap, fieldDescMap };
- }
- /*
- * 具體的后臺驗證過程
- */
- public static ValidityResult validity(Object currObj) throws IllegalArgumentException, IllegalAccessException,
- SecurityException, NoSuchMethodException, InvocationTargetException {
- Class aClass = currObj.getClass();
- String classFullName = aClass.getPackage().getName() + "." + aClass.getName();
- Field[] fieldArr = aClass.getDeclaredFields();
- Map validityRuleMap = allValidityRuleMap.get(classFullName);
- Map fieldDescMap = allFieldDescMap.get(classFullName);
- List canNotNullFieldNameList = (List) validityRuleMap.get("canNotNullFieldNameList");
- List isIntegerValiditerRuleInfoList = (List) validityRuleMap.get("isIntegerValiditerRuleInfoList");
- ValidityResult validityResult = new ValidityResult();
- for (int j = 0; j < canNotNullFieldNameList.size(); j++) {
- String currFieldName = (String) canNotNullFieldNameList.get(j);
- String getMethodName = "get" + currFieldName.substring(0, 1).toUpperCase() + currFieldName.substring(1);
- Method getFieldValueMethod = aClass.getMethod(getMethodName);
- String fieldValue = ((String) getFieldValueMethod.invoke(currObj));
- if (fieldValue == null || fieldValue.equals("")) {
- System.out.println(fieldDescMap.get(currFieldName) + " 不可以為空 ! ");
- validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 不可以為空 ! ");
- }
- }
- for (int j = 0; j < isIntegerValiditerRuleInfoList.size(); j++) {
- IsIntegerValiditerRuleInfo isIntegerValiditerRuleInfo = (IsIntegerValiditerRuleInfo) isIntegerValiditerRuleInfoList
- .get(j);
- String currFieldName = isIntegerValiditerRuleInfo.getFieldName();
- String getMethodName = "get" + currFieldName.substring(0, 1).toUpperCase() + currFieldName.substring(1);
- Method getFieldValueMethod = aClass.getMethod(getMethodName);
- String fieldValue = ((String) getFieldValueMethod.invoke(currObj));
- int minWidth = isIntegerValiditerRuleInfo.getMinWidth();
- int maxWidth = isIntegerValiditerRuleInfo.getMaxWidth();
- int minValue = isIntegerValiditerRuleInfo.getMinValue();
- int maxValue = isIntegerValiditerRuleInfo.getMaxValue();
- if (StringUtils.isInteger(fieldValue)) {
- if (fieldValue.length() < minWidth) {
- validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 寬度不可以小于 " + minWidth + "! ");
- }
- if (fieldValue.length() > maxWidth) {
- validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 寬度不可以大于 " + maxWidth + "! ");
- }
- if (Integer.parseInt(fieldValue) < minValue) {
- validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 的值不可以小于 " + minValue + "! ");
- }
- if (Integer.parseInt(fieldValue) > maxValue) {
- validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 的值不可以大于 " + maxValue + "! ");
- }
- }
- else {
- validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 必須是整數(shù)格式 ! ");
- }
- }
- return validityResult;
- }
- public static String[] getPojoBeanPackageName() {
- return pojoBeanPackageName;
- }
- public static void setPojoBeanPackageName(String[] pojoBeanPackageName) {
- PojoBeanAnnotationValiditer.pojoBeanPackageName = pojoBeanPackageName;
- }
- public static String getJsValiditerFilePath() {
- return jsValiditerFilePath;
- }
- public static void setJsValiditerFilePath(String jsValiditerFilePath) {
- PojoBeanAnnotationValiditer.jsValiditerFilePath = jsValiditerFilePath;
- }
- public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, SecurityException,
- NoSuchMethodException, InvocationTargetException, ClassNotFoundException, IOException {
- PojoBeanAnnotationValiditer.setPojoBeanPackageName(new String[] { "com.javaest.validity.test.pojo" });
- PojoBeanAnnotationValiditer.setJsValiditerFilePath("JS\\VALIDITY");
- PojoBeanAnnotationValiditer
- .loadAllClassAnnotationValidityInfoInPackage(new String[] { "com.javaest.validity.test.pojo" });
- Student aStudent = new Student();
- aStudent.setAddress("吉林省長春市二道區(qū)");
- aStudent.setId("");
- aStudent.setAge("9");
- ValidityResult validityResult = PojoBeanAnnotationValiditer.validity(aStudent);
- }
- }</SPAN>
下邊是一個加好了標(biāo)注的Student類
- public class Student {
- @CanNotNull
- @FieldDesc("姓名")
- private String name;
- @CanNotNull
- @FieldDesc("性別")
- private String sex;
- @IsInteger(minValue=18,maxValue=60)
- @CanNotNull
- @FieldDesc("年齡")
- private String age;
- @CanNotNull
- @FieldDesc("編碼")
- private String id;
- private String address;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getSex() {
- return sex;
- }
- 。。。。。。。。。。
- }
在家閑著寫代碼真好。