javaBean与Map<String,Object>互转

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. packagejavaStudyDemo.bean.reflect.test;
  2. importjava.beans.BeanInfo;
  3. importjava.beans.Introspector;
  4. importjava.beans.PropertyDescriptor;
  5. importjava.lang.reflect.Method;
  6. importjava.util.HashMap;
  7. importjava.util.Map;
  8. importjavaStudyDemo.others.PersonBean;
  9. importorg.apache.commons.beanutils.BeanUtils;
  10. /**
  11. *当把Person类作为BeanUtilTest的内部类时,程序出错<br>
  12. *java.lang.NoSuchMethodException:Property'**'hasnosettermethod<br>
  13. *本质:内部类和单独文件中的类的区别<br>
  14. *BeanUtils.populate方法的限制:<br>
  15. *Theclassmustbepublic,andprovideapublicconstructorthatacceptsnoarguments.<br>
  16. *Thisallowstoolsandapplicationstodynamicallycreatenewinstancesofyourbean,<br>
  17. *withoutnecessarilyknowingwhatJavaclassnamewillbeusedaheadoftime
  18. */
  19. publicclassBeanUtilTest{
  20. publicstaticvoidmain(String[]args){
  21. PersonBeanperson=newPersonBean();
  22. Map<String,Object>mp=newHashMap<String,Object>();
  23. mp.put("name","Mike");
  24. mp.put("age",25);
  25. mp.put("mN","male");
  26. //将map转换为bean
  27. transMap2Bean2(mp,person);
  28. System.out.println("---transMap2BeanMapInfo:");
  29. for(Map.Entry<String,Object>entry:mp.entrySet()){
  30. System.out.println(entry.getKey()+":"+entry.getValue());
  31. }
  32. System.out.println("---BeanInfo:");
  33. System.out.println("name:"+person.getName());
  34. System.out.println("age:"+person.getAge());
  35. System.out.println("mN:"+person.getmN());
  36. //将javaBean转换为map
  37. Map<String,Object>map=transBean2Map(person);
  38. System.out.println("---transBean2MapMapInfo:");
  39. for(Map.Entry<String,Object>entry:map.entrySet()){
  40. System.out.println(entry.getKey()+":"+entry.getValue());
  41. }
  42. }
  43. //Map-->Bean2:利用org.apache.commons.beanutils工具类实现Map-->Bean
  44. publicstaticvoidtransMap2Bean2(Map<String,Object>map,Objectobj){
  45. if(map==null||obj==null){
  46. return;
  47. }
  48. try{
  49. BeanUtils.populate(obj,map);
  50. }catch(Exceptione){
  51. System.out.println("transMap2Bean2Error"+e);
  52. }
  53. }
  54. //Map-->Bean1:利用Introspector,PropertyDescriptor实现Map-->Bean
  55. publicstaticvoidtransMap2Bean(Map<String,Object>map,Objectobj){
  56. try{
  57. BeanInfobeanInfo=Introspector.getBeanInfo(obj.getClass());
  58. PropertyDescriptor[]propertyDescriptors=beanInfo.getPropertyDescriptors();
  59. for(PropertyDescriptorproperty:propertyDescriptors){
  60. Stringkey=property.getName();
  61. if(map.containsKey(key)){
  62. Objectvalue=map.get(key);
  63. //得到property对应的setter方法
  64. Methodsetter=property.getWriteMethod();
  65. setter.invoke(obj,value);
  66. }
  67. }
  68. }catch(Exceptione){
  69. System.out.println("transMap2BeanError"+e);
  70. }
  71. return;
  72. }
  73. //Bean-->Map1:利用Introspector和PropertyDescriptor将Bean-->Map
  74. publicstaticMap<String,Object>transBean2Map(Objectobj){
  75. if(obj==null){
  76. returnnull;
  77. }
  78. Map<String,Object>map=newHashMap<String,Object>();
  79. try{
  80. BeanInfobeanInfo=Introspector.getBeanInfo(obj.getClass());
  81. PropertyDescriptor[]propertyDescriptors=beanInfo.getPropertyDescriptors();
  82. for(PropertyDescriptorproperty:propertyDescriptors){
  83. Stringkey=property.getName();
  84. //过滤class属性
  85. if(!key.equals("class")){
  86. //得到property对应的getter方法
  87. Methodgetter=property.getReadMethod();
  88. Objectvalue=getter.invoke(obj);
  89. map.put(key,value);
  90. }
  91. }
  92. }catch(Exceptione){
  93. System.out.println("transBean2MapError"+e);
  94. }
  95. returnmap;
  96. }
  97. }


  1. publicclassPersonBean{
  2. privateStringname;
  3. privateIntegerage;
  4. privateStringmN;
  5. /**
  6. *@returnthemN
  7. */
  8. publicStringgetmN(){
  9. returnmN;
  10. }
  11. /**
  12. *@parammNthemNtoset
  13. */
  14. publicvoidsetmN(StringmN){
  15. this.mN=mN;
  16. }
  17. /**
  18. *@returnthename
  19. */
  20. publicStringgetName(){
  21. returnname;
  22. }
  23. /**
  24. *@paramnamethenametoset
  25. */
  26. publicvoidsetName(Stringname){
  27. this.name=name;
  28. }
  29. /**
  30. *@returntheage
  31. */
  32. publicIntegergetAge(){
  33. returnage;
  34. }
  35. /**
  36. *@paramagetheagetoset
  37. */
  38. publicvoidsetAge(Integerage){
  39. this.age=age;
  40. }
  41. }


总结: 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值