自定义注解验证参数

使用注解去验证某个对象属性是否按照我们的注解来赋值的。

例子:我们需要定义一个MyLimit的注解,这个注解里面规定了类属性的限制;编写注解解析;在类中属性使用注解;最后测试是否是我们需要的效果。

定义MyLimit注解:

  1. @Target({ ElementType.FIELD })  
  2. // 标注只能放在类或接口的注解  
  3. @Retention(RetentionPolicy.RUNTIME)  
  4. // 在运行时有效  
  5. public @interface MyLimit {  
  6.     //这个字段是否为必填  
  7.     boolean isNotNull() default false;  
  8.     // 字段描述  
  9.     String description() default “”;  
  10.     int MaxLength() default 0;  
  11.     int MinLength() default 0;  
  12.     //表示这个字段是否为int类型  
  13.     boolean isInt() default false;  
  14.     int MaxNum() default 30;  
  15.     int MinNum() default 18;  
  16. }  
@Target({ ElementType.FIELD })
// 标注只能放在类或接口的注解
@Retention(RetentionPolicy.RUNTIME)
// 在运行时有效
public @interface MyLimit {
    //这个字段是否为必填
    boolean isNotNull() default false;
    // 字段描述
    String description() default "";
    int MaxLength() default 0;
    int MinLength() default 0;
    //表示这个字段是否为int类型
    boolean isInt() default false;
    int MaxNum() default 30;
    int MinNum() default 18;
}
编写注解的解析:VerifyAnnotationMyLimit类,这个里面使用一个List来存放验证的错误信息,getListExceptions()方法返回这个List,可以通过annotationMyLimit.getListExceptions().size()!=0来判断验证是否成功,不成功可以取得错误信息:

VerifyAnnotationMyLimit:

  1. import java.lang.reflect.Field;  
  2. import java.util.ArrayList;  
  3.   
  4. public class VerifyAnnotationMyLimit {  
  5.     private MyLimit limit;  
  6.     private Class obj;  
  7.     private ArrayList<Exception> ListExceptions;  
  8.   
  9.     public VerifyAnnotationMyLimit(Object object) throws Exception {  
  10.         obj = object.getClass();  
  11.         ListExceptions = new ArrayList<Exception>();  
  12.         Field[] fields = obj.getDeclaredFields();  
  13.         for (Field field : fields) {  
  14.             // 设置field为private时设置可以访问权限,  
  15.             field.setAccessible(true);  
  16.             // 开始验证  
  17.             verify(field, object);  
  18.             // 重新对field设置权限  
  19.             field.setAccessible(false);  
  20.   
  21.         }  
  22.     }  
  23.   
  24.     public ArrayList<Exception> getListExceptions() {  
  25.         return ListExceptions;  
  26.     }  
  27.   
  28.     private void verify(Field field, Object object) throws Exception {  
  29.         limit = field.getAnnotation(MyLimit.class);  
  30.         // 检查这个field是否被MyLimit注释  
  31.         if (!field.isAnnotationPresent(MyLimit.class)) {  
  32.             return;  
  33.         }  
  34.         // 取出object对象中的field值  
  35.         Object objectvalue = field.get(object);  
  36.         String description = ”“.equals(limit.description()) ? field.getName()  
  37.                 : limit.description();  
  38.   
  39.         // 先验证是否为必填,如果必填且value为空,则抛出异常,如果不是必填,那我们  
  40.         if (limit.isNotNull()) {  
  41.             if (“”.equals(objectvalue) || objectvalue == null) {  
  42.                 ListExceptions.add(new Exception(description + “不能为空”));  
  43.             }  
  44.         } else {  
  45.             // 不是必填项先检查是否有值,没有就直接返回,有就继续向下验证  
  46.             if (objectvalue == null) {  
  47.                 return;  
  48.             }  
  49.         }  
  50.   
  51.         if (limit.isInt()) {  
  52.             int value = Integer.valueOf(objectvalue.toString());  
  53.             if (value < limit.MinNum() || value > limit.MaxNum()) {  
  54.                 ListExceptions.add(new Exception(description + “必须在”  
  55.                         + limit.MinNum() + ”到” + limit.MaxNum() + “之间”));  
  56.             }  
  57.             return;  
  58.         }  
  59.   
  60.         if (objectvalue.toString().length() < limit.MinLength()  
  61.                 || objectvalue.toString().length() > limit.MaxLength()) {  
  62.             ListExceptions.add(new Exception(description + “长度必须在”  
  63.                     + limit.MinLength() + ”到” + limit.MaxLength() + “之间”));  
  64.         }  
  65.     }  
  66. }  
import java.lang.reflect.Field;
import java.util.ArrayList;

public class VerifyAnnotationMyLimit {
    private MyLimit limit;
    private Class obj;
    private ArrayList<Exception> ListExceptions;

    public VerifyAnnotationMyLimit(Object object) throws Exception {
        obj = object.getClass();
        ListExceptions = new ArrayList<Exception>();
        Field[] fields = obj.getDeclaredFields();
        for (Field field : fields) {
            // 设置field为private时设置可以访问权限,
            field.setAccessible(true);
            // 开始验证
            verify(field, object);
            // 重新对field设置权限
            field.setAccessible(false);

        }
    }

    public ArrayList<Exception> getListExceptions() {
        return ListExceptions;
    }

    private void verify(Field field, Object object) throws Exception {
        limit = field.getAnnotation(MyLimit.class);
        // 检查这个field是否被MyLimit注释
        if (!field.isAnnotationPresent(MyLimit.class)) {
            return;
        }
        // 取出object对象中的field值
        Object objectvalue = field.get(object);
        String description = "".equals(limit.description()) ? field.getName()
                : limit.description();

        // 先验证是否为必填,如果必填且value为空,则抛出异常,如果不是必填,那我们
        if (limit.isNotNull()) {
            if ("".equals(objectvalue) || objectvalue == null) {
                ListExceptions.add(new Exception(description + "不能为空"));
            }
        } else {
            // 不是必填项先检查是否有值,没有就直接返回,有就继续向下验证
            if (objectvalue == null) {
                return;
            }
        }

        if (limit.isInt()) {
            int value = Integer.valueOf(objectvalue.toString());
            if (value < limit.MinNum() || value > limit.MaxNum()) {
                ListExceptions.add(new Exception(description + "必须在"
                        + limit.MinNum() + "到" + limit.MaxNum() + "之间"));
            }
            return;
        }

        if (objectvalue.toString().length() < limit.MinLength()
                || objectvalue.toString().length() > limit.MaxLength()) {
            ListExceptions.add(new Exception(description + "长度必须在"
                    + limit.MinLength() + "到" + limit.MaxLength() + "之间"));
        }
    }
}
Students类时注解的使用者:

  1. public class Students {  
  2.     private int id;  
  3.     @MyLimit(description=“学生的姓名”,MaxLength=5,MinLength=2,isNotNull=true)  
  4.     private String name;  
  5.     @MyLimit(description=“学生的年龄”,isNotNull=true,isInt=true)  
  6.     private int age;  
  7.     @MyLimit(MaxLength=200,isNotNull=true)  
  8.     private String addr;  
  9.     @MyLimit(description=“学生所在城市”,MaxLength=20)  
  10.     private String city;  
  11.     set…get…  
  12.     @Override  
  13.     public String toString() {  
  14.         return “Students [id=” + id + “, name=” + name + “, age=” + age  
  15.                 + ”, addr=” + addr + “, city=” + city + “]”;  
  16.     }     
  17. }  
public class Students {
    private int id;
    @MyLimit(description="学生的姓名",MaxLength=5,MinLength=2,isNotNull=true)
    private String name;
    @MyLimit(description="学生的年龄",isNotNull=true,isInt=true)
    private int age;
    @MyLimit(MaxLength=200,isNotNull=true)
    private String addr;
    @MyLimit(description="学生所在城市",MaxLength=20)
    private String city;
    set...get...
    @Override
    public String toString() {
        return "Students [id=" + id + ", name=" + name + ", age=" + age
                + ", addr=" + addr + ", city=" + city + "]";
    }   
}
在Students类中我们没有在id的属性上设置注解,所以不会对id进行验证;对name属性设置规定了长度在2到5之间,而且是必填项;在age上规定了这个是必填项,是一个int类型的,所以会使用注解对int类型默认的范围18到哦30之间;而对于addr属性只是规定了200长度,但是必填。

最后到了测试部分:

  1. public static void main(String[] args) {  
  2.         // TODO Auto-generated method stub  
  3.         Students students = new Students();  
  4.         students.setName(”abcdefghijklmn”);  
  5.         students.setAddr(”“);  
  6.         students.setAge(230);  
  7.         try {//传人Students对象进行验证  
  8.             VerifyAnnotationMyLimit annotationMyLimit = new VerifyAnnotationMyLimit(students);  
  9.             if(annotationMyLimit.getListExceptions().size()!=0){  
  10.                 for (Exception exception : annotationMyLimit.getListExceptions()) {  
  11.                     System.out.println(”错误:”+exception.getMessage());  
  12.                 }  
  13.             }  
  14.         } catch (Exception e) {  
  15.             // TODO Auto-generated catch block  
  16.             System.out.println(e.getMessage());  
  17.             e.printStackTrace();  
  18.         }  
  19.           
  20.         System.out.println(students.toString());  
  21.     }  
public static void main(String[] args) {
        // TODO Auto-generated method stub
        Students students = new Students();
        students.setName("abcdefghijklmn");
        students.setAddr("");
        students.setAge(230);
        try {//传人Students对象进行验证
            VerifyAnnotationMyLimit annotationMyLimit = new VerifyAnnotationMyLimit(students);
            if(annotationMyLimit.getListExceptions().size()!=0){
                for (Exception exception : annotationMyLimit.getListExceptions()) {
                    System.out.println("错误:"+exception.getMessage());
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println(e.getMessage());
            e.printStackTrace();
        }

        System.out.println(students.toString());
    }

if(annotationMyLimit.getListExceptions().size()!=0)判断是验证有错误;

for (Exception exception : annotationMyLimit.getListExceptions()) {
System.out.println(“错误:”+exception.getMessage());//输出错误信息。
}
结果:


当我们改动一些值时:

  1. students.setName(“张三”);  
  2. students.setAddr(”xxx省xxx市xxx县”);  
  3. students.setAge(23);  
       students.setName("张三");
        students.setAddr("xxx省xxx市xxx县");
        students.setAge(23);

我们按照规定填写时就没有错误了,

但是这样还是有弊端的,因为我们是使用已经设置好属性的对象去验证了,等于是先给Students赋值,再去验证我们赋值是否正确,有了一些中间操作。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值