浅谈java反射和自定义注解的综合应用实例

时间:2021-08-05 23:29:45

前言

前几天学习了反射自定义注解,刚好工作中遇到一个小问题:前台传递到后台的必填字段为空,导致不能插入数据库。就是这样一个小问题,让我考虑到是否可以做一个通用的方法,让前台传递过来的必填字段在后台也校验一遍,如果传递为空,则把响应字段返回提示。因此,我考虑的是用注解的方式,在必填字段上面定义,利用反射得到必填字段的字段名,判断是否为空,并返回响应的信息。

需求模拟

假设客户有:姓名,年龄,地址,手机号码,身份证号等信息,而我们是做金融业务,所以关键是看客户的三要素:姓名,身份证号,手机号码。我们要保证前台传递过来的这三个值不为空。
废话不多说,直接上代码。只看红框里面的即可。

目录结构

浅谈java反射和自定义注解的综合应用实例

客户信息类:customer

这个是个实体类,我们在:姓名,身份证号码,手机号码上都用了我们的自定义注解。
 

java" id="highlighter_187418">
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

我们在这个类里面主要用了反射的知识,得到带有自定义注解的字段,并取得这个对象的值进行判断

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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:响应实体类

封装了响应的成功失败以及一些信息

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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();
    }
  }
   
   
   
}

输出结果

浅谈java反射和自定义注解的综合应用实例

第一次三个值都为空,提示三个都是必填的,第二次因为姓名赋值了,所以提示另外两个是必填的,本次实验宣告结束,本人知识有限,若有更好的方法欢迎指正

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://blog.csdn.net/daochuwenziyao/article/details/77755314?utm_source=tuicool&utm_medium=referral