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
- 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'**'hasnosettermethod<br>
- *本质:内部类和单独文件中的类的区别<br>
- *BeanUtils.populate方法的限制:<br>
- *Theclassmustbepublic,andprovideapublicconstructorthatacceptsnoarguments.<br>
- *Thisallowstoolsandapplicationstodynamicallycreatenewinstancesofyourbean,<br>
- *withoutnecessarilyknowingwhatJavaclassnamewillbeusedaheadoftime
- */
- publicclassBeanUtilTest{
- publicstaticvoidmain(String[]args){
- PersonBeanperson=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("---transMap2BeanMapInfo:");
- for(Map.Entry<String,Object>entry:mp.entrySet()){
- System.out.println(entry.getKey()+":"+entry.getValue());
- }
- System.out.println("---BeanInfo:");
- 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("---transBean2MapMapInfo:");
- for(Map.Entry<String,Object>entry:map.entrySet()){
- System.out.println(entry.getKey()+":"+entry.getValue());
- }
- }
- //Map-->Bean2:利用org.apache.commons.beanutils工具类实现Map-->Bean
- publicstaticvoidtransMap2Bean2(Map<String,Object>map,Objectobj){
- if(map==null||obj==null){
- return;
- }
- try{
- BeanUtils.populate(obj,map);
- }catch(Exceptione){
- System.out.println("transMap2Bean2Error"+e);
- }
- }
- //Map-->Bean1:利用Introspector,PropertyDescriptor实现Map-->Bean
- publicstaticvoidtransMap2Bean(Map<String,Object>map,Objectobj){
- try{
- BeanInfobeanInfo=Introspector.getBeanInfo(obj.getClass());
- PropertyDescriptor[]propertyDescriptors=beanInfo.getPropertyDescriptors();
- for(PropertyDescriptorproperty:propertyDescriptors){
- Stringkey=property.getName();
- if(map.containsKey(key)){
- Objectvalue=map.get(key);
- //得到property对应的setter方法
- Methodsetter=property.getWriteMethod();
- setter.invoke(obj,value);
- }
- }
- }catch(Exceptione){
- System.out.println("transMap2BeanError"+e);
- }
- return;
- }
- //Bean-->Map1:利用Introspector和PropertyDescriptor将Bean-->Map
- publicstaticMap<String,Object>transBean2Map(Objectobj){
- if(obj==null){
- returnnull;
- }
- Map<String,Object>map=newHashMap<String,Object>();
- try{
- BeanInfobeanInfo=Introspector.getBeanInfo(obj.getClass());
- PropertyDescriptor[]propertyDescriptors=beanInfo.getPropertyDescriptors();
- for(PropertyDescriptorproperty:propertyDescriptors){
- Stringkey=property.getName();
- //过滤class属性
- if(!key.equals("class")){
- //得到property对应的getter方法
- Methodgetter=property.getReadMethod();
- Objectvalue=getter.invoke(obj);
- map.put(key,value);
- }
- }
- }catch(Exceptione){
- System.out.println("transBean2MapError"+e);
- }
- returnmap;
- }
- }
- publicclassPersonBean{
- privateStringname;
- privateIntegerage;
- privateStringmN;
- /**
- *@returnthemN
- */
- publicStringgetmN(){
- returnmN;
- }
- /**
- *@parammNthemNtoset
- */
- publicvoidsetmN(StringmN){
- this.mN=mN;
- }
- /**
- *@returnthename
- */
- publicStringgetName(){
- returnname;
- }
- /**
- *@paramnamethenametoset
- */
- publicvoidsetName(Stringname){
- this.name=name;
- }
- /**
- *@returntheage
- */
- publicIntegergetAge(){
- returnage;
- }
- /**
- *@paramagetheagetoset
- */
- publicvoidsetAge(Integerage){
- 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