javaBean與Map互轉

1. 爲何要實現javaBean與Map<String,Object>相互轉換?

用過spring的都知道spring的MVC框架中有一個BaseCommandController對象,利用這個對象咱們就能夠很方便的將從客戶端傳遞過來的參數封裝到一個JavaBean對象中去,而不須要咱們request.getParameter("name");bean.setName(name);了,從而也簡化了很多的工做。若是你們用過BeanUtils.populate的話,就知道,這個方法是能夠很方便的將request提交的頁面表單自動填寫到你建立的對象中java

2. 如何實現javaBean與Map<String,Object>相互轉換?

方法1: 利用Java.beans.Introspector和java.beans.PropertyDescriptor實現 javaBean與Map<String,Object>互轉spring

方法2: 利用org.apache.commons.beanutils.BeanUtils工具類,BeanUtils.populate實現Map 轉換爲javaBean apache

  1 package javaStudyDemo.bean.reflect.test;
  2 
  3 import java.beans.BeanInfo;
  4 import java.beans.Introspector;
  5 import java.beans.PropertyDescriptor;
  6 import java.lang.reflect.Method;
  7 import java.util.HashMap;
  8 import java.util.Map;
  9 import javaStudyDemo.others.PersonBean;
 10 
 11 import org.apache.commons.beanutils.BeanUtils;
 12 
 13 /**
 14  * 當把Person類做爲BeanUtilTest的內部類時,程序出錯<br>
 15  * java.lang.NoSuchMethodException: Property '**' has no setter method<br>
 16  * 本質:內部類 和 單獨文件中的類的區別 <br>
 17  * BeanUtils.populate方法的限制:<br>
 18  * The class must be public, and provide a public constructor that accepts no arguments. <br>
 19  * This allows tools and applications to dynamically create new instances of your bean, <br>
 20  * without necessarily knowing what Java class name will be used ahead of time
 21  */
 22 public class BeanUtilTest {
 23 
 24     public static void main(String[] args) {
 25 
 26         PersonBean person = new PersonBean();
 27         Map<String, Object> mp = new HashMap<String, Object>();
 28         mp.put("name", "Mike");
 29         mp.put("age", 25);
 30         mp.put("mN", "male");
 31 
 32         // 將map轉換爲bean
 33         transMap2Bean2(mp, person);
 34 
 35         System.out.println("--- transMap2Bean Map Info: ");
 36         for (Map.Entry<String, Object> entry : mp.entrySet()) {
 37             System.out.println(entry.getKey() + ": " + entry.getValue());
 38         }
 39 
 40         System.out.println("--- Bean Info: ");
 41         System.out.println("name: " + person.getName());
 42         System.out.println("age: " + person.getAge());
 43         System.out.println("mN: " + person.getmN());
 44 
 45         // 將javaBean 轉換爲map
 46         Map<String, Object> map = transBean2Map(person);
 47 
 48         System.out.println("--- transBean2Map Map Info: ");
 49         for (Map.Entry<String, Object> entry : map.entrySet()) {
 50             System.out.println(entry.getKey() + ": " + entry.getValue());
 51         }
 52 
 53     }
 54 
 55     // Map --> Bean 2: 利用org.apache.commons.beanutils 工具類實現 Map --> Bean
 56     public static void transMap2Bean2(Map<String, Object> map, Object obj) {
 57         if (map == null || obj == null) {
 58             return;
 59         }
 60         try {
 61             BeanUtils.populate(obj, map);
 62         } catch (Exception e) {
 63             System.out.println("transMap2Bean2 Error " + e);
 64         }
 65     }
 66 
 67     // Map --> Bean 1: 利用Introspector,PropertyDescriptor實現 Map --> Bean
 68     public static void transMap2Bean(Map<String, Object> map, Object obj) {
 69 
 70         try {
 71             BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
 72             PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
 73 
 74             for (PropertyDescriptor property : propertyDescriptors) {
 75                 String key = property.getName();
 76 
 77                 if (map.containsKey(key)) {
 78                     Object value = map.get(key);
 79                     // 獲得property對應的setter方法
 80                     Method setter = property.getWriteMethod();
 81                     setter.invoke(obj, value);
 82                 }
 83 
 84             }
 85 
 86         } catch (Exception e) {
 87             System.out.println("transMap2Bean Error " + e);
 88         }
 89 
 90         return;
 91 
 92     }
 93 
 94     // Bean --> Map 1: 利用Introspector和PropertyDescriptor 將Bean --> Map
 95     public static Map<String, Object> transBean2Map(Object obj) {
 96 
 97         if(obj == null){
 98             return null;
 99         }        
100         Map<String, Object> map = new HashMap<String, Object>();
101         try {
102             BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
103             PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
104             for (PropertyDescriptor property : propertyDescriptors) {
105                 String key = property.getName();
106 
107                 // 過濾class屬性
108                 if (!key.equals("class")) {
109                     // 獲得property對應的getter方法
110                     Method getter = property.getReadMethod();
111                     Object value = getter.invoke(obj);
112 
113                     map.put(key, value);
114                 }
115 
116             }
117         } catch (Exception e) {
118             System.out.println("transBean2Map Error " + e);
119         }
120 
121         return map;
122 
123     }
124 }
 1 public class PersonBean {
 2 
 3     private String  name;
 4     private Integer age;
 5     private String  mN;
 6 
 7     /**
 8      * @return the mN
 9      */
10     public String getmN() {
11         return mN;
12     }
13 
14     /**
15      * @param mN the mN to set
16      */
17     public void setmN(String mN) {
18         this.mN = mN;
19     }
20 
21 
22     /**
23      * @return the name
24      */
25     public String getName() {
26         return name;
27     }
28 
29     /**
30      * @param name the name to set
31      */
32     public void setName(String name) {
33         this.name = name;
34     }
35 
36     /**
37      * @return the age
38      */
39     public Integer getAge() {
40         return age;
41     }
42 
43     /**
44      * @param age the age to set
45      */
46     public void setAge(Integer age) {
47         this.age = age;
48     }
49 
50 }

總結:  javaBean與Map<String,Object>互轉利用到了java的內省( Introspector )和反射(reflect)機制。 其思路爲: 經過類 Introspector 來獲取某個對象的 BeanInfo 信息,而後經過 BeanInfo 來獲取屬性的描述器PropertyDescriptor,再利用屬性描述器獲取某個屬性對應的 getter/setter 方法,而後經過反射機制來getter和setter。app

什麼是內省? 框架

內省是 Java 語言對 Bean 類屬性、事件的一種缺省處理方法。例如類 PersonBean中有屬性 name, 那咱們能夠經過 getName,setName 來獲得其值或者設置新的值。經過 getName/setName 來訪問 name 屬性,這就是默認的規則。 Java 中提供了一套 API 用來訪問某個屬性的 getter/setter 方法,經過這些 API 能夠使你不須要了解這個規則(但你最好仍是要搞清楚),這些 API 存放於包 java.beans 中。注意: PersonBean中屬性mN的getter/setter方法必須知足javaBean命名規範,即getmN,不能寫做getMN,不然轉換失敗。ide

已驗證;工具

相關文章
相關標籤/搜索