您的位置:资讯频道 > 技术文档 > Java组件开发

基于JAVA标注实现统一的前台(JS层)后台(JAVA层)

来源:博客   作者:javaest   时间:2008-04-21  点击:291 次
通过标注的方式进行前后台的统一验证的好处是很多的,增强前后台验证的一致性,减少代码的重复,不需要前台与一份验证,后台再写一份了。

本人想基于这种方式写一个基于Annotation的完整的Validator的开源的小框架,但发现要做的事情很多,工作量很大,要一点一点的来,一点一点的完善,最后闲时写了个大 概,与大家一起探讨,

通过JAVA标注将前台和后台的验证规则标到JAVA的值对象的类中。
Validator在初始化的过程中,一次性读入JAVA的值对象的类中验证规则的标注信息,并生成前台需要的校验的JS文件。
前台页面可以直接引入自动生成的校验的JS文件,进行校验。a
后台得到从前台请求request绑定好值的JAVA的值对象,通过AnnotationValidator类进行验证。

以下是Annotation标注的代码。

进行不可以为空的校验标注

@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类的标注信息一次性的读取到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]);
    }
   }
  }
  /*
  * 对具体的一个类的标注做处理,读入字段描述 信息,读入非空验证信息,读入整数验证信息,并根据这些信息生成JS代码。
  */

  private static Map[] loadValidityRuleAndCreateValidityJsFile(Class currClass) throws IllegalArgumentException,
   IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException,
   OException {
     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");
     }
      //读入整数验证信息
     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) + "的数值太小!');}\n");
       }
      if (maxValue < Integer.MAX_VALUE) {
       validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName + ".value*1>maxValue){alert('"
        + fieldDescMap.get(currFieldName) + "的数值太大!');}\n");
      }
     }
    }
    Map<String, List> classValidityRuleMap = new HashMap<String, List>();
     classValidityRuleMap.put("canNotNullFieldNameList", canNotNullFieldNameList);
    classValidityRuleMap.put("isIntegerValiditerRuleInfoList", isIntegerValiditerRuleInfoList);
    //根据这些信息生成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) + " 必须是整数格式 ! ");

    }
   }
   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("吉林省长春市二道区");
  aStudent.setId("");
  aStudent.setAge("9");
  ValidityResult validityResult = PojoBeanAnnotationValiditer.validity(aStudent);
 }

}</SPAN>
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类的标注信息一次性的读取到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]);
  }
 }
}
/*
* 对具体的一个类的标注做处理,读入字段描述 信息,读入非空验证信息,读入整数验证信息,并根据这些信息生成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");
  }
  //读入整数验证信息
  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) + "的数值太小!');}\n");
 }
 if (maxValue < Integer.MAX_VALUE) {
  validityIsIntegerJsStrBuf.append("if(document.all." + currFieldName + ".value*1>maxValue){alert('"
   + fieldDescMap.get(currFieldName) + "的数值太大!');}\n");
 }
}
}
Map<String, List> classValidityRuleMap = new HashMap<String, List>();
classValidityRuleMap.put("canNotNullFieldNameList", canNotNullFieldNameList);
classValidityRuleMap.put("isIntegerValiditerRuleInfoList", isIntegerValiditerRuleInfoList);
//根据这些信息生成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) + " 必须是整数格式 ! ");
  }
 }
 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("吉林省长春市二道区");
 aStudent.setId("");
 aStudent.setAge("9");
 ValidityResult validityResult = PojoBeanAnnotationValiditer.validity(aStudent);
 }
}


下边是一个加好了标注的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;
 }
。。。。。。。。。。
}