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 }
二、报文参数的接收实体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 }
三、利用反射的校验方法

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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)