隨筆-1  評論-8  文章-1  trackbacks-0

          基于JAVA標注實現統一的前臺(JS層)后臺(JAVA層)想法

          原創,非轉
          基于JAVA標注實現統一的前臺(JS層)后臺(JAVA層)想法[/b]
          通過標注的方式進行前后臺的統一驗證的好處是很多的,增強前后臺驗證的一致性,減少代碼的重復,不需要前臺與一份驗證,后臺再寫一份了。

          本人想基于這種方式寫一個基于Annotation的完整的Validator的開源的小框架,但發現要做的事情很多,工作量很大,要一點一點的來,一點一點的完善,最后閑時寫了個大 概,與大家一起探討
          1. 通過JAVA標注將前臺和后臺的驗證規則標到JAVA的值對象的類中。
          2. Validator在初始化的過程中,一次性讀入JAVA的值對象的類中驗證規則的標注信息,并生成前臺需要的校驗的JS文件。
          3. 前臺頁面可以直接引入自動生成的校驗的JS文件,進行校驗。a
          4. 后臺得到從前臺請求request綁定好值的JAVA的值對象,通過AnnotationValidator類進行驗證。

          以下是Annotation標注的代碼。

          進行不可以為空的校驗標注
          1. @Retention (RetentionPolicy.RUNTIME)   
          2. @Target(ElementType.FIELD)   
          3.   
          4. public @interface CanNotNull {     
          5.   
          6. }  
          進行是否是整數的校驗標注
          1. @Retention(RetentionPolicy.RUNTIME)   
          2. @Target(ElementType.FIELD)   
          3. public @interface IsInteger {   
          4.     public int minWidth() default 1;   
          5.     public int maxWidth() default Integer.MAX_VALUE;   
          6.     public  int minValue() default Integer.MIN_VALUE;   
          7.     public  int maxValue() default Integer.MAX_VALUE;   
          8.   
          9. }  
          用于添寫字段中文的標注


          1. @Retention(RetentionPolicy.RUNTIME)   
          2. @Target(ElementType.FIELD)   
          3. public @interface FieldDesc {   
          4.     public String value();   
          5.   
          6. }  

          驗證器的代碼:
          1. package com.javaest.validity.process;   
          2.   
          3. import java.io.BufferedWriter;   
          4. import java.io.File;   
          5. import java.io.FileWriter;   
          6. import java.io.IOException;   
          7. import java.lang.reflect.Field;   
          8. import java.lang.reflect.InvocationTargetException;   
          9. import java.lang.reflect.Method;   
          10. import java.util.ArrayList;   
          11. import java.util.HashMap;   
          12. import java.util.List;   
          13. import java.util.Map;   
          14.   
          15. import com.javaest.util.StringUtils;   
          16. import com.javaest.validity.annotation.CanNotNull;   
          17. import com.javaest.validity.annotation.FieldDesc;   
          18. import com.javaest.validity.annotation.IsInteger;   
          19. import com.javaest.validity.test.pojo.Student;   
          20.   
          21. public class PojoBeanAnnotationValiditer {   
          22.     private static Map<String, Map> allValidityRuleMap = new HashMap<String, Map>();   
          23.     private static Map<String, Map> allFieldDescMap = new HashMap<String, Map>();   
          24.     private static String jsValiditerFilePath;   
          25.     private static String[] pojoBeanPackageName;   
          26.     /**  
          27.      *   
          28.         將指定的包下邊的所有Pojo類的標注信息一次性的讀取到Map中,以備以后驗證對象時使用  
          29.      */  
          30.     public static void loadAllClassAnnotationValidityInfoInPackage(String[] packageNameArr)   
          31.             throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchMethodException,   
          32.             InvocationTargetException, ClassNotFoundException, IOException {   
          33.         for (int i = 0; i < packageNameArr.length; i++) {   
          34.             List<Class> classList = ReflectUtils.getAllClassInPackage(packageNameArr[i]);   
          35.             for (int j = 0; j < classList.size(); j++) {   
          36.                 Class currClass = classList.get(j);   
          37.                 String classFullName = currClass.getPackage().getName() + "." + currClass.getName();   
          38.                 Map[] validityRuleMapAndFieldDescMap = loadValidityRuleAndCreateValidityJsFile(currClass);   
          39.                 allValidityRuleMap.put(classFullName, validityRuleMapAndFieldDescMap[0]);   
          40.                 allFieldDescMap.put(classFullName, validityRuleMapAndFieldDescMap[1]);   
          41.             }   
          42.         }   
          43.     }   
          44.     /*  
          45.      * 對具體的一個類的標注做處理,讀入字段描述 信息,讀入非空驗證信息,讀入整數驗證信息,并根據這些信息生成JS代碼。  
          46.      */  
          47.   
          48.     private static Map[] loadValidityRuleAndCreateValidityJsFile(Class currClass) throws IllegalArgumentException,   
          49.             IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException, IOException {   
          50.         StringBuffer validityCanNotNullJsStrBuf = new StringBuffer();   
          51.         StringBuffer validityIsIntegerJsStrBuf = new StringBuffer();   
          52.         Field[] fieldArr = currClass.getDeclaredFields();   
          53.         List<String> canNotNullFieldNameList = new ArrayList<String>();   
          54.         List<IsIntegerValiditerRuleInfo> isIntegerValiditerRuleInfoList = new ArrayList<IsIntegerValiditerRuleInfo>();   
          55.         Map<String, String> fieldDescMap = new HashMap<String, String>();   
          56.         for (int i = 0; i < fieldArr.length; i++) {   
          57.             String currFieldName = fieldArr[i].getName();   
          58.             //讀入字段描述 信息   
          59.             FieldDesc fieldDescAnnotation = fieldArr[i].getAnnotation(FieldDesc.class);   
          60.             if (fieldDescAnnotation != null) {   
          61.                 String fieldDesc = fieldDescAnnotation.value();   
          62.                 System.out.println(fieldDesc);   
          63.                 fieldDescMap.put(currFieldName, fieldDesc);   
          64.             }   
          65.             else {   
          66.                 fieldDescMap.put(currFieldName, currFieldName);   
          67.             }   
          68.             //讀入非空驗證信息   
          69.             if (fieldArr[i].isAnnotationPresent(CanNotNull.class)) {                   
          70.                 canNotNullFieldNameList.add(currFieldName);   
          71.                 validityCanNotNullJsStrBuf.append("if(document.all." + currFieldName + ".value.trim()==\"\"){alert('"  
          72.                         + fieldDescMap.get(currFieldName) + "不可以為空');}\n");   
          73.             }   
          74.             //讀入整數驗證信息   
          75.             IsInteger isIntegerAnnotation = fieldArr[i].getAnnotation(IsInteger.class);   
          76.             if (isIntegerAnnotation != null) {   
          77.                 int minWidth = isIntegerAnnotation.minWidth();   
          78.                 int maxWidth = isIntegerAnnotation.maxWidth();   
          79.                 int minValue = isIntegerAnnotation.minValue();   
          80.                 int maxValue = isIntegerAnnotation.maxValue();   
          81.                 IsIntegerValiditerRuleInfo isIntegerValiditerRuleInfo = new IsIntegerValiditerRuleInfo(currFieldName,   
          82.                         minWidth, maxWidth, minValue, maxValue);   
          83.                 isIntegerValiditerRuleInfoList.add(isIntegerValiditerRuleInfo);   
          84.                 if (minWidth > 0) {   
          85.                     validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName   
          86.                             + ".value.length()<minWidth){alert('" + fieldDescMap.get(currFieldName) + "寬度不夠!');}\n");   
          87.                 }   
          88.                 if (maxWidth < Integer.MAX_VALUE) {   
          89.                     validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName   
          90.                             + ".value.length()>maxWidth){alert('" + fieldDescMap.get(currFieldName) + "寬度太長!');}\n");   
          91.                 }   
          92.                 if (minValue > Integer.MIN_VALUE) {   
          93.                     validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName + ".value*1<minValue){alert('"  
          94.                             + fieldDescMap.get(currFieldName) + "的數值太小!');}\n");   
          95.                 }   
          96.                 if (maxValue < Integer.MAX_VALUE) {   
          97.                     validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName + ".value*1>maxValue){alert('"  
          98.                             + fieldDescMap.get(currFieldName) + "的數值太大!');}\n");   
          99.                 }   
          100.             }   
          101.         }   
          102.         Map<String, List> classValidityRuleMap = new HashMap<String, List>();   
          103.         classValidityRuleMap.put("canNotNullFieldNameList", canNotNullFieldNameList);   
          104.         classValidityRuleMap.put("isIntegerValiditerRuleInfoList", isIntegerValiditerRuleInfoList);   
          105.         //根據這些信息生成JS代碼   
          106.         BufferedWriter jsFileWriter = new BufferedWriter(new FileWriter(new File(jsValiditerFilePath   
          107.                 + java.io.File.separator + currClass.getName() + ".js")));   
          108.         jsFileWriter.write(validityCanNotNullJsStrBuf.toString());   
          109.         jsFileWriter.write(validityIsIntegerJsStrBuf.toString());   
          110.         jsFileWriter.close();   
          111.         return new Map[] { classValidityRuleMap, fieldDescMap };   
          112.   
          113.     }   
          114.     /*  
          115.      * 具體的后臺驗證過程  
          116.      */  
          117.   
          118.     public static ValidityResult validity(Object currObj) throws IllegalArgumentException, IllegalAccessException,   
          119.             SecurityException, NoSuchMethodException, InvocationTargetException {   
          120.         Class aClass = currObj.getClass();   
          121.         String classFullName = aClass.getPackage().getName() + "." + aClass.getName();   
          122.         Field[] fieldArr = aClass.getDeclaredFields();   
          123.   
          124.         Map validityRuleMap = allValidityRuleMap.get(classFullName);   
          125.         Map fieldDescMap = allFieldDescMap.get(classFullName);   
          126.         List canNotNullFieldNameList = (List) validityRuleMap.get("canNotNullFieldNameList");   
          127.         List isIntegerValiditerRuleInfoList = (List) validityRuleMap.get("isIntegerValiditerRuleInfoList");   
          128.         ValidityResult validityResult = new ValidityResult();   
          129.         for (int j = 0; j < canNotNullFieldNameList.size(); j++) {   
          130.             String currFieldName = (String) canNotNullFieldNameList.get(j);   
          131.             String getMethodName = "get" + currFieldName.substring(01).toUpperCase() + currFieldName.substring(1);   
          132.             Method getFieldValueMethod = aClass.getMethod(getMethodName);   
          133.             String fieldValue = ((String) getFieldValueMethod.invoke(currObj));   
          134.             if (fieldValue == null || fieldValue.equals("")) {   
          135.                 System.out.println(fieldDescMap.get(currFieldName) + " 不可以為空 ! ");   
          136.                 validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 不可以為空 ! ");   
          137.             }   
          138.         }   
          139.   
          140.         for (int j = 0; j < isIntegerValiditerRuleInfoList.size(); j++) {   
          141.             IsIntegerValiditerRuleInfo isIntegerValiditerRuleInfo = (IsIntegerValiditerRuleInfo) isIntegerValiditerRuleInfoList   
          142.                     .get(j);   
          143.             String currFieldName = isIntegerValiditerRuleInfo.getFieldName();   
          144.             String getMethodName = "get" + currFieldName.substring(01).toUpperCase() + currFieldName.substring(1);   
          145.             Method getFieldValueMethod = aClass.getMethod(getMethodName);   
          146.             String fieldValue = ((String) getFieldValueMethod.invoke(currObj));   
          147.             int minWidth = isIntegerValiditerRuleInfo.getMinWidth();   
          148.             int maxWidth = isIntegerValiditerRuleInfo.getMaxWidth();   
          149.             int minValue = isIntegerValiditerRuleInfo.getMinValue();   
          150.             int maxValue = isIntegerValiditerRuleInfo.getMaxValue();   
          151.   
          152.             if (StringUtils.isInteger(fieldValue)) {   
          153.                 if (fieldValue.length() < minWidth) {   
          154.                     validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 寬度不可以小于 " + minWidth + "! ");   
          155.                 }   
          156.                 if (fieldValue.length() > maxWidth) {   
          157.                     validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 寬度不可以大于 " + maxWidth + "! ");   
          158.                 }   
          159.                 if (Integer.parseInt(fieldValue) < minValue) {   
          160.                     validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 的值不可以小于 " + minValue + "! ");   
          161.                 }   
          162.                 if (Integer.parseInt(fieldValue) > maxValue) {   
          163.                     validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 的值不可以大于 " + maxValue + "! ");   
          164.                 }   
          165.   
          166.             }   
          167.             else {   
          168.   
          169.                 validityResult.addValidityInfo(fieldDescMap.get(currFieldName) + " 必須是整數格式 ! ");   
          170.   
          171.             }   
          172.         }   
          173.         return validityResult;   
          174.   
          175.     }   
          176.   
          177.     public static String[] getPojoBeanPackageName() {   
          178.         return pojoBeanPackageName;   
          179.     }   
          180.   
          181.     public static void setPojoBeanPackageName(String[] pojoBeanPackageName) {   
          182.         PojoBeanAnnotationValiditer.pojoBeanPackageName = pojoBeanPackageName;   
          183.     }   
          184.   
          185.     public static String getJsValiditerFilePath() {   
          186.         return jsValiditerFilePath;   
          187.     }   
          188.   
          189.     public static void setJsValiditerFilePath(String jsValiditerFilePath) {   
          190.         PojoBeanAnnotationValiditer.jsValiditerFilePath = jsValiditerFilePath;   
          191.     }   
          192.   
          193.     public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, SecurityException,   
          194.             NoSuchMethodException, InvocationTargetException, ClassNotFoundException, IOException {   
          195.         PojoBeanAnnotationValiditer.setPojoBeanPackageName(new String[] { "com.javaest.validity.test.pojo" });   
          196.         PojoBeanAnnotationValiditer.setJsValiditerFilePath("JS\\VALIDITY");   
          197.         PojoBeanAnnotationValiditer   
          198.                 .loadAllClassAnnotationValidityInfoInPackage(new String[] { "com.javaest.validity.test.pojo" });   
          199.         Student aStudent = new Student();   
          200.         aStudent.setAddress("吉林省長春市二道區");   
          201.         aStudent.setId("");   
          202.         aStudent.setAge("9");   
          203.         ValidityResult validityResult = PojoBeanAnnotationValiditer.validity(aStudent);   
          204.     }   
          205.   
          206. }</SPAN>  


          下邊是一個加好了標注的Student類

          1. public class Student {   
          2.     @CanNotNull    
          3.     @FieldDesc("姓名")   
          4.     private String name;   
          5.     @CanNotNull    
          6.     @FieldDesc("性別")   
          7.     private String sex;   
          8.     @IsInteger(minValue=18,maxValue=60)   
          9.     @CanNotNull  
          10.     @FieldDesc("年齡")   
          11.     private String age;   
          12.     @CanNotNull  
          13.     @FieldDesc("編碼")   
          14.     private String id;   
          15.     private String address;   
          16.     public String getName() {   
          17.         return name;   
          18.     }   
          19.     public void setName(String name) {   
          20.         this.name = name;   
          21.     }   
          22.     public String getSex() {   
          23.         return sex;   
          24.     }   
          25. 。。。。。。。。。。   
          26. }  


          在家閑著寫代碼真好。
          posted on 2008-04-17 09:37 javaest 閱讀(1885) 評論(7)  編輯  收藏

          評論:
          # re: 基于JAVA標注實現統一的前臺(JS層)后臺(JAVA層) 2008-04-17 10:57 | Libo
          這個思路不錯.hibernate validator 只是實現后臺的驗證.如果能和這個結合起來可能用途會更廣泛.  回復  更多評論
            
          # re: 基于JAVA標注實現統一的前臺(JS層)后臺(JAVA層) 2008-06-02 17:57 | 懶人
          你家是二道區的么?  回復  更多評論
            
          # re: 基于JAVA標注實現統一的前臺(JS層)后臺(JAVA層)[未登錄] 2008-06-05 13:12 | javaest
          @懶人
          對,你如果知道?
            回復  更多評論
            
          # re: 基于JAVA標注實現統一的前臺(JS層)后臺(JAVA層) 2008-08-04 09:52 | 殘夢追月
          不錯,是不是可以使用正則表達式來驗證呢?就是說在使用的時候,只有一個標記,里面有個參數,輸入正則表達式…………就可用驗證了。  回復  更多評論
            
          # re: 基于JAVA標注實現統一的前臺(JS層)后臺(JAVA層) 2008-08-04 09:53 | 殘夢追月
          他看的這里:

          aStudent.setAddress("吉林省長春市二道區");   回復  更多評論
            
          # re: 基于JAVA標注實現統一的前臺(JS層)后臺(JAVA層)[未登錄] 2010-04-14 09:59 | fangjava
          能看到  回復  更多評論
            
          # re: 基于JAVA標注實現統一的前臺(JS層)后臺(JAVA層)[未登錄] 2010-04-14 10:00 | fangjava
          能看到我的留言么??  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 长泰县| 城步| 丹江口市| 沅陵县| 明溪县| 珲春市| 唐海县| 保定市| 曲水县| 独山县| 恭城| 东至县| 安乡县| 万山特区| 渭南市| 凤翔县| 竹溪县| 宁安市| 密云县| 会理县| 津市市| 葫芦岛市| 桓仁| 黄骅市| 罗平县| 来安县| 延边| 新蔡县| 安泽县| 彭山县| 乌审旗| 汉寿县| 甘肃省| 同江市| 远安县| 德庆县| 贵港市| 德昌县| 桐梓县| 海丰县| 安溪县|