javaBean与Map<String,Object>相互转换

来源:互联网 发布:virtuozo软件制作dem 编辑:程序博客网 时间:2024/05/21 18:31
1. 为什么要实现javaBean与Map<String,Object>相互转换?

用过spring的都知道spring的MVC框架中有一个BaseCommandController对象,利用这个对象我们就可以很方便的将从客户端传递过来的参数封装到一个JavaBean对象中去,而不需要我们request.getParameter("name");bean.setName(name);了,从而也简化了不少的工作。如果大家用过BeanUtils.populate的话,就知道,这个方法是可以很方便的将request提交的页面表单自动填写到你创建的对象中

2. 如何实现javaBean与Map<String,Object>相互转换?

方法1: 利用java.beans.Introspector和java.beans.PropertyDescriptor实现 javaBean与Map<String,Object>互转

方法2: 利用org.apache.commons.beanutils.BeanUtils工具类,BeanUtils.populate实现Map 转换为javaBean

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
packagejavaStudyDemo.bean.reflect.test; 
   
importjava.beans.BeanInfo; 
importjava.beans.Introspector; 
importjava.beans.PropertyDescriptor; 
importjava.lang.reflect.Method; 
importjava.util.HashMap; 
importjava.util.Map; 
importjavaStudyDemo.others.PersonBean; 
   
importorg.apache.commons.beanutils.BeanUtils; 
   
/**
 * 当把Person类作为BeanUtilTest的内部类时,程序出错<br>
 * java.lang.NoSuchMethodException: Property '**' has no setter method<br>
 * 本质:内部类 和 单独文件中的类的区别 <br>
 * BeanUtils.populate方法的限制:<br>
 * The class must be public, and provide a public constructor that accepts no arguments. <br>
 * This allows tools and applications to dynamically create new instances of your bean, <br>
 * without necessarily knowing what Java class name will be used ahead of time
 */ 
publicclass BeanUtilTest { 
   
    publicstatic void main(String[] args) { 
   
        PersonBean person = newPersonBean(); 
        Map<String, Object> mp = newHashMap<String, Object>(); 
        mp.put("name","Mike"); 
        mp.put("age",25); 
        mp.put("mN","male"); 
   
        // 将map转换为bean 
        transMap2Bean2(mp, person); 
   
        System.out.println("--- transMap2Bean Map Info: "); 
        for(Map.Entry<String, Object> entry : mp.entrySet()) { 
            System.out.println(entry.getKey() + ": " + entry.getValue()); 
        
   
        System.out.println("--- Bean Info: "); 
        System.out.println("name: " + person.getName()); 
        System.out.println("age: " + person.getAge()); 
        System.out.println("mN: " + person.getmN()); 
   
        // 将javaBean 转换为map 
        Map<String, Object> map = transBean2Map(person); 
   
        System.out.println("--- transBean2Map Map Info: "); 
        for(Map.Entry<String, Object> entry : map.entrySet()) { 
            System.out.println(entry.getKey() + ": " + entry.getValue()); 
        
   
    
   
    // Map --> Bean 2: 利用org.apache.commons.beanutils 工具类实现 Map --> Bean 
    publicstatic void transMap2Bean2(Map<String, Object> map, Object obj) { 
        if(map == null|| obj == null) { 
            return
        
        try
            BeanUtils.populate(obj, map); 
        }catch(Exception e) { 
            System.out.println("transMap2Bean2 Error " + e); 
        
    
   
    // Map --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean 
    publicstatic void transMap2Bean(Map<String, Object> map, Object obj) { 
   
        try
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); 
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); 
   
            for(PropertyDescriptor property : propertyDescriptors) { 
                String key = property.getName(); 
   
                if(map.containsKey(key)) { 
                    Object value = map.get(key); 
                    // 得到property对应的setter方法 
                    Method setter = property.getWriteMethod(); 
                    setter.invoke(obj, value); 
                
   
            
   
        }catch(Exception e) { 
            System.out.println("transMap2Bean Error " + e); 
        
   
        return
   
    
   
    // Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map 
    publicstatic Map<String, Object> transBean2Map(Object obj) { 
   
        if(obj == null){ 
            returnnull
        }         
        Map<String, Object> map = newHashMap<String, Object>(); 
        try
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); 
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); 
            for(PropertyDescriptor property : propertyDescriptors) { 
                String key = property.getName(); 
   
                // 过滤class属性 
                if(!key.equals("class")) { 
                    // 得到property对应的getter方法 
                    Method getter = property.getReadMethod(); 
                    Object value = getter.invoke(obj); 
   
                    map.put(key, value); 
                
   
            
        }catch(Exception e) { 
            System.out.println("transBean2Map Error " + e); 
        
   
        returnmap; 
   
    

 

 

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
publicclass PersonBean { 
   
    privateString  name; 
    privateInteger age; 
    privateString  mN; 
   
    /**
     * @return the mN
     */ 
    publicString getmN() { 
        returnmN; 
    
   
    /**
     * @param mN the mN to set
     */ 
    publicvoid setmN(String mN) { 
        this.mN = mN; 
    
   
   
    /**
     * @return the name
     */ 
    publicString getName() { 
        returnname; 
    
   
    /**
     * @param name the name to set
     */ 
    publicvoid setName(String name) { 
        this.name = name; 
    
   
    /**
     * @return the age
     */ 
    publicInteger getAge() { 
        returnage; 
    
   
    /**
     * @param age the age to set
     */ 
    publicvoid setAge(Integer age) { 
        this.age = age; 
    
   

 

 

总结:  javaBean与Map<String,Object>互转利用到了java的内省( Introspector )和反射(reflect)机制。 其思路为: 通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器PropertyDescriptor,再利用属性描述器获取某个属性对应的 getter/setter 方法,然后通过反射机制来getter和setter。


什么是内省? 

内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 PersonBean中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。 Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些 API 存放于包 java.beans 中。注意: PersonBean中属性mN的getter/setter方法必须满足javaBean命名规范,即getmN,不能写作getMN,否则转换失败。详情参考  http://blog.renren.com/share/236384819/5598710664