java利用反射和注解作数据校验
1、自定义注解
@Target(value={ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NumCheck {
int min() default 1;
int max() default 100;
String message() default "success";
}
2.创建校验工具
public class ValidatorUtil {
public static String validate(Object obj){
// 反射获取注解
Class<?> cla = obj.getClass();
Field[] fields = cla.getDeclaredFields();
for(Field field : fields){
NumCheck numCheck = field.getAnnotation(NumCheck.class);
if(null!= numCheck){
int min = numCheck.min();
int max = numCheck.max();
try {
Type genericType = field.getGenericType();
if(genericType.getTypeName().equals("int") ||
genericType.getTypeName().equals("java.lang.Integer")){
field.setAccessible(true);
int num = field.getInt(obj);
if(num < min || num > max){
return numCheck.message();
}
}
if(genericType.getTypeName().equals("java.lang.String")){
field.setAccessible(true);
String str = (String)field.get(obj);
if(null == str){
str = "";
}
int length = str.length();
if(length < min || length > max){
return numCheck.message();
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return "Success";
}
}
3、自定义实体类
public class Student{
@NumCheck(min=18,max=50,message="年龄必须在18岁到50岁之间,包含18岁和50岁")
private int age ;
@NumCheck(min=2,max=5,message="姓名最少2位,最多5位")
private String name ;
boolean sex ;
protected double score ;
}
4、测试
public static void main(String[] args) {
Student student = new Student();
student.setAge(30);
student.setName("chengya");
String checkResult = ValidatorUtil.validate(student);
System.out.println(checkResult);
}
测试过程中出现过两个问题:
1、第一次测试时,实体类的age属性加了注解,反射却没有获取到注解。后来发现是注解的Retention写漏了,导致运行时注解不生效。
2、当实体类未设置name属性值时,String str = (String)field.get(obj); 获取到的str是null,导致str.length()抛出空指针异常。