浅谈java反射和自定义注解的综合应用实例
程序员文章站
2024-02-24 08:58:22
前言
前几天学习了反射和自定义注解,刚好工作中遇到一个小问题:前台传递到后台的必填字段为空,导致不能插入数据库。就是这样一个小问题,让我考虑到是否可以做一个通用的方法...
前言
前几天学习了反射和自定义注解,刚好工作中遇到一个小问题:前台传递到后台的必填字段为空,导致不能插入数据库。就是这样一个小问题,让我考虑到是否可以做一个通用的方法,让前台传递过来的必填字段在后台也校验一遍,如果传递为空,则把响应字段返回提示。因此,我考虑的是用注解的方式,在必填字段上面定义,利用反射得到必填字段的字段名,判断是否为空,并返回响应的信息。
需求模拟
假设客户有:姓名,年龄,地址,手机号码,身份证号等信息,而我们是做金融业务,所以关键是看客户的三要素:姓名,身份证号,手机号码。我们要保证前台传递过来的这三个值不为空。
废话不多说,直接上代码。只看红框里面的即可。
目录结构
客户信息类:customer
这个是个实体类,我们在:姓名,身份证号码,手机号码上都用了我们的自定义注解。
package com.dao.chu.po; /** * * <p>title: customer</p> * <p>description:客户信息实体 </p> */ public class customer { private int id; @isrequired private string name; // 姓名 @isrequired private string idnum; // 身份证号码 @isrequired private string phone; // 手机号 private string sex; // 性别 private int age; // 年龄 private string address; // 地址 @override public string tostring() { return "customer [id=" + id + ", name=" + name + ", idnum=" + idnum + ", phone=" + phone + ", sex=" + sex + ", age=" + age + ", address=" + address + "]"; } public int getid() { return id; } public void setid(int id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } public string getidnum() { return idnum; } public void setidnum(string idnum) { this.idnum = idnum; } public string getphone() { return phone; } public void setphone(string phone) { this.phone = phone; } public string getsex() { return sex; } public void setsex(string sex) { this.sex = sex; } public int getage() { return age; } public void setage(int age) { this.age = age; } public string getaddress() { return address; } public void setaddress(string address) { this.address = address; } }
自定义注解类:isrequired
package com.dao.chu.po; import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; /** * * <p>title: isrequired</p> * <p>description: 字段是否必填 </p> */ @retention(value = retentionpolicy.runtime) @target(value = {elementtype.field}) public @interface isrequired { /** * * <p>title: isrequired</p> * <p>description:true:必填 false:非必填 </p> * @return */ boolean isrequired() default true; }
关键工具类:poutils
我们在这个类里面主要用了反射的知识,得到带有自定义注解的字段,并取得这个对象的值进行判断
package com.dao.chu.po; import java.beans.introspectionexception; import java.beans.propertydescriptor; import java.lang.reflect.field; import java.lang.reflect.invocationtargetexception; import javax.jws.webresult; import com.sun.xml.internal.ws.util.stringutils; /** * * <p>title: poutils</p> * <p>description:po操作工具类 </p> */ @suppresswarnings("unused") public class poutils { /** * <p>title: getproperties</p> * <p>description: 获取javabean属性通用方法 </p> * @param t * @param beanname * @return * @throws illegalaccessexception * @throws illegalargumentexception * @throws invocationtargetexception * @throws introspectionexception */ private static <t> object getproperties(t t, string beanname) throws illegalaccessexception, illegalargumentexception, invocationtargetexception, introspectionexception { object namevalue = new propertydescriptor(beanname, t.getclass()).getreadmethod().invoke(t); return namevalue; } /** * <p>title: isfieldblank</p> * <p>description:判断前台传过来的必填字段是否为空 ,不正确则将相应字段返回 </p> * @param t * @return * @throws illegalaccessexception * @throws illegalargumentexception * @throws invocationtargetexception * @throws introspectionexception */ public static <t> respbody isfieldblank(t t) throws illegalaccessexception, illegalargumentexception, invocationtargetexception, introspectionexception { respbody respbody = new respbody(); stringbuffer sb = new stringbuffer(); field[] declaredfields = t.getclass().getdeclaredfields(); for (field field : declaredfields) { field.setaccessible(true); string name = field.getname(); boolean fieldhasanno = field.isannotationpresent(isrequired.class); if (fieldhasanno) { isrequired annotation = field.getannotation(isrequired.class); boolean required = annotation.isrequired(); if (required) { object value = getproperties(t, name); if (null == value) { sb.append(name + ","); } } } } if (null==sb.tostring()||"".equals(sb.tostring())) { respbody.issuccess(); } respbody.setsuccess(false); respbody.setmsg(sb.tostring().substring(0,sb.tostring().lastindexof(",")) + " is required"); return respbody; } }
respbody:响应实体类
封装了响应的成功失败以及一些信息
package com.dao.chu.po; /** * * <p>title: respbody</p> * <p>description: 响应实体类</p> */ public class respbody { private boolean issuccess = true; private string msg; private object data; public boolean issuccess() { return issuccess; } public void setsuccess(boolean issuccess) { this.issuccess = issuccess; } public string getmsg() { return msg; } public void setmsg(string msg) { this.msg = msg; } public object getdata() { return data; } public void setdata(object data) { this.data = data; } public respbody(boolean issuccess, string msg, object data) { super(); this.issuccess = issuccess; this.msg = msg; this.data = data; } public respbody(boolean issuccess, string msg) { super(); this.issuccess = issuccess; this.msg = msg; } public respbody() { } @override public string tostring() { return "returnbody [issuccess=" + issuccess + ", msg=" + msg + ", data=" + data + "]"; } }
测试类:isrequiredtest
package com.dao.chu.po; /** * * <p>title: isrequiredtest</p> * <p>description: 必填成员变量测试类</p> */ public class isrequiredtest { public static void main(string[] args) { customer customer = new customer(); try { //=========第一次不赋值========== respbody respbody = poutils.isfieldblank(customer); //不通过则返回提示信息 if (!respbody.issuccess()) { system.out.println("1."+respbody.getmsg()); } //=========第二次给姓名赋值========== customer.setname("张三"); respbody = poutils.isfieldblank(customer); //不通过则返回提示信息 if (!respbody.issuccess()) { system.out.println("2."+respbody.getmsg()); } } catch (exception e) { e.printstacktrace(); } } }
输出结果
第一次三个值都为空,提示三个都是必填的,第二次因为姓名赋值了,所以提示另外两个是必填的,本次实验宣告结束,本人知识有限,若有更好的方法欢迎指正
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 详解Android平台上读写NFC标签
下一篇: java实现监听u盘示例分享