java基础之反射二 接口参数校验

在实际开发过程中,系统都有相应的关联系统,两个系统间的交互一般是通过接口传送所需参数,接口参数都会要求,比如有些参数必输,有些参数有长度要求等等。因此,在收到关联系统的接口参数时,都会对参数做校验。

  下面是利用反射对接口参数做校验的简单Demo。

一、定义注解CustomAnno,这个demo只关注是否必输和长度

复制代码
 1 import java.lang.annotation.Documented;
 2 import java.lang.annotation.ElementType;
 3 import java.lang.annotation.Retention;
 4 import java.lang.annotation.RetentionPolicy;
 5 import java.lang.annotation.Target;
 6 /**
 7  *  自定义注解
 8  *      @Target:标识注解的适用范围
 9  *          ElementType.TYPE:表示CustomAnno注解可以作用在类上
10  *          ElementType.METHOD:表示CustomAnno注解可以作用在方法上
11  *          ElementType.FIELD:表示CustomAnno注解可以作用在类上
12  *      @Retention:表示注解的生命周期
13  *          RUNTIME:在运行时有效
14  *          SOURCE:在源文件中有效
15  *      @Documented:主要作用在生成javadoc文档,标记注解
16  */
17 @Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
18 @Retention(RetentionPolicy.RUNTIME)
19 @Documented
20 public @interface CustomAnno {
21     
22     int length() default 0;
23     
24     boolean required() default false;
25 }
View Code
复制代码

二、报文参数的接收实体Student

复制代码
 1 import com.anno.CustomAnno;
 2 /**
 3  * 接收接口参数的实体
 4  */
 5 public class Student {
 6     
 7     @CustomAnno(required = true, length = 30)
 8     private String name;
 9     
10     @CustomAnno(required = true, length = 3)
11     private Integer age;
12     
13     @CustomAnno(required = false, length = 30)
14     private String sex;
15     
16     @CustomAnno(required = false, length = 20)
17     public double weight;
18     
19     @CustomAnno(required = false, length = 20)
20     protected double height;
21 
22     public Student() {
23         super();
24     }
25 
26     public Student(String name, Integer age, String sex) {
27         super();
28         this.name = name;
29         this.age = age;
30         this.sex = sex;
31     }
32     
33     public Student(String name, Integer age, String sex, double weight, double height) {
34         super();
35         this.name = name;
36         this.age = age;
37         this.sex = sex;
38         this.weight = weight;
39         this.height = height;
40     }
41 
42     public String getName() {
43         return name;
44     }
45 
46     public void setName(String name) {
47         this.name = name;
48     }
49 
50     public Integer getAge() {
51         return age;
52     }
53 
54     public void setAge(Integer age) {
55         this.age = age;
56     }
57 
58     public String getSex() {
59         return sex;
60     }
61 
62     public void setSex(String sex) {
63         this.sex = sex;
64     }
65     
66     public double getWeight() {
67         return weight;
68     }
69 
70     public void setWeight(double weight) {
71         this.weight = weight;
72     }
73     
74     public double getHeight() {
75         return height;
76     }
77 
78     public void setHeight(double height) {
79         this.height = height;
80     }
81 
82 }
View Code
复制代码

三、利用反射的校验方法

复制代码
 1 public class AnnoReflect {
 2     public static void main(String[] args) throws Exception {
 3         try {
 4             Class<?> clazz = Class.forName("com.reflect.Student");
 5             // 版本一
 6             Object instance_v1 = clazz.newInstance();
 7 //            validVersion_1(clazz, instance_v1);
 8             
 9             // 版本二
10             Student instance_v2 = getStudent();
11             boolean valResult = validVersion_2(clazz, instance_v2);
12             if(!valResult) {
13                 System.out.println("入参报文有误,请检查");
14             }
15             System.out.println("入参报文无误,业务参数落库");
16         } catch (ClassNotFoundException e) {
17             e.printStackTrace();
18         }
19     }
20     /**
21      *     版本一
22      * @param clazz Class对象
23      * @param instance  实例对象
24      * @throws Exception 异常
25      */
26     public static void validVersion_1(Class<?> clazz, Object instance) throws Exception {
27         Field[] fields = clazz.getDeclaredFields();
28         for (Field field : fields) {
29             field.setAccessible(true);
30             if("name".equals(field.getName())) {
31                 field.set(instance, "张三");
32             }
33             CustomAnno declaredAnnotation = field.getDeclaredAnnotation(CustomAnno.class);
34             if(declaredAnnotation.required()) {
35                 Object object = field.get(instance);
36                 if(object == null || "".equals(object)) {
37                     System.out.println(field.getName() + "的入参为" + object + ", 报文参数异常请检查");
38                 }
39             }
40         }
41     }
42     
43     /**
44      *     版本二
45      * @param clazz Class对象
46      * @param instance  实例对象
47      * @throws Exception 异常
48      */
49     public static boolean validVersion_2(Class<?> clazz, Object instance) throws Exception {
50         Field[] fields = clazz.getDeclaredFields();
51         for (Field field : fields) {
52             Annotation[] annotations = field.getAnnotations();
53             for (Annotation annotation : annotations) {
54                 if(annotation instanceof CustomAnno) {
55                     field.setAccessible(true);
56                     boolean required = ((CustomAnno) annotation).required();
57                     if(required) {
58                         if(field.get(instance) == null || "".equals(field.get(instance))){
59                             System.out.println(field.getName() + "的入参为: " + field.get(instance) + "内容不能为空");
60                             return false;
61                         }
62                     }
63                     int length = ((CustomAnno) annotation).length();    
64                     if(field.get(instance).toString().length() < 0 || field.get(instance).toString().length() > length) {
65                         System.out.println(field.getName() + "的入参为: " + field.get(instance) + ", 长度超长");
66                         return false;
67                     }
68                 }
69             }
70         }
71         return true;
72     }
73     /**
74      * 模拟接口参数被实体对象接收的情况
75      */
76     public static Student getStudent() {
77         // 模拟正常报文
78         return new Student("张三", 15, "男", 130.0, 172.0);
79         
80         // 模拟必输字段内容为空的异常报文
81 //        return new Student("", 15, "男", 130.0, 172.0);
82         
83         // 模拟必输字段内容超长异常报文
84 //        return new Student("张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三", 15, "男", 130.0, 172.0);
85     }
View Code
复制代码

 

posted @   无虑的小猪  阅读(381)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示