一、为什么要实现javaBean与Map<String,Object>相互转换

Spring中的BaseCommandController对象可以将传递过来的参数封装到一个JavaBean对象中去,而不需要我们再频繁使用request.getParameter()方法,再像bean去设置属性了,从而简化了开发工作。BeanUtils.populate方法将request提交的页面表单自动填写到你创建的对象中去。

二、如何实现javabean与Map<String,Object>之间的转换

1、利用java.beans.Introspector和java.beans.PropertyDescription实现javaBean与Map<String,Object>相互转换

2、利用org.apache.commons.beanutils.BeanUtils工具类,BeanUtils.popluate实现Map转换为javaBean

package javaStudyDemo.bean.test;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javaStudyDemo.others.PersonBean; import org.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
*/
public class BeanUtilTest { public static void main(String[] args) { Person person = new Person();
Map<String, Object> mp = new HashMap<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
public static 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
public static 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
public static Map<String, Object> transBean2Map(Object obj) { if(obj == null){
return null;
}
Map<String, Object> map = new HashMap<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);
} return map; }
}
public class Person{

    private String  name;
private Integer age;
private String mN; /**
* @return the mN
*/
public String getmN() {
return mN;
} /**
* @param mN the mN to set
*/
public void setmN(String mN) {
this.mN = mN;
} /**
* @return the name
*/
public String getName() {
return name;
} /**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
} /**
* @return the age
*/
public Integer getAge() {
return age;
} /**
* @param age the age to set
*/
public void 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,否则转换失败。

JavaBean与Map<String,Object>相互转换的更多相关文章

  1. javaBean与Map<String,Object>互转

    背景:有时候想不通阿帕奇的BeanUtils是怎么进行map和Bean互相转化的. 工作闲暇之余,自己写个一小段代码,一探究竟,试试才发现,原来一切并非我们想的那么什么和复杂. 注:这里只是简单实例, ...

  2. 用第三方工具类,将JavaBean、List、Map<String,Object>转成JSON文本

    导入第三方jar包: >commons-beanutils-1.7.0.jar >commons-collections-3.1.jar >commons-lang-2.5.jar ...

  3. 分页查询和分页缓存查询,List<Map<String, Object>>遍历和Map遍历

    分页查询 String sql = "返回所有符合条件记录的待分页SQL语句"; int start = (page - 1) * limit + 1; int end = pag ...

  4. 使用 JDBC 和 JavaTemplate 查询SQL语句返回 List<Map<String,Object>>

    使用JDBC执行sql语句返回List 类型: public class JdbcUtil { private static Log log = LogFactory.getLog(JdbcUtil. ...

  5. List<Map<String,Object>>使用Java代码遍历

    List<Map<String,Object>>的结果集怎么使用Java代码遍历以获取String,Object的值: package excel; import java.u ...

  6. java中对List<Map<String,Object>>中的中文汉字排序

    import java.text.Collator;import java.util.ArrayList;import java.util.Collections;import java.util.C ...

  7. 迭代输出Map和List<Map<String,Object>>的方法

    一.Map<String,Object> String:key的类型 Object:value的类型,value可能是String,或者int类型,什么类型都可以 对于Map接口来说,本身 ...

  8. List<Map<String, Object>>相关

    2016年8月6日13:53:00 --------------------------- List<Map<String, Object>> List集合新增列 则需要: L ...

  9. java中List<Map<String, Object>>关于null的判断

    List<Map<String, Object>> selectTmFileInfo = fileInfoService.selectTmFileInfoByToken(cTo ...

随机推荐

  1. si4438 cca 侦听

    /* set GPIO0 for RSSI interrupt / CCA */txbuf[0] = CMD_GPIO_PIN_CFG;txbuf[1] = 27; /* GPIO[0] = 27: ...

  2. HTML——图片自动轮换和手动轮换

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. git中文乱码解决方案

    解决方案: 在bash提示符下输入: git config --global core.quotepath false core.quotepath设为false的话,就不会对0x80以上的字符进行q ...

  4. Yarn NodeManager restart

    一.介绍默认Yarn NodeManager重启后会断开所有当前正在运行的container的状态,这意味着重启后需要重新启动container进程,该特性的作用就是把NM的状态临时保存到本地,重启后 ...

  5. Hive Tuning(一) 连接策略

    群里共享了一本hive调优的书记,名叫<Hive Tunning>,就忍不住开始看了,也顺便记录一下自己学到的东西,备忘! 首先,这是hive的数据摘要,别问我什么意思,我也没看懂. 好, ...

  6. 二、Linux 静态IP,动态IP配置

    Linux 静态IP,动态IP配置 第一步:激活网卡 系统装好后默认的网卡是eth0,用下面的命令将这块网卡激活. # ifconfig eth0 up 第二步:设置网卡进入系统时启动 想要每次开机就 ...

  7. C++对析构函数的误解

    C++析构前言 析构函数在什么时候会自动被调用,在什么时候需要手动来调用,真不好意思说偶学过C++…今日特此拨乱反正. C++析构误解正文 对象在构造的时候系统会分配内存资源,对一些数据成员进行初始化 ...

  8. e581. Animating an Array of Images in an Application

    This is the simplest application to animate an array of images. import java.awt.*; import javax.swin ...

  9. Erlang的Web库和框架

    ChicagoBoss,Nitrogen ,Zotontic,BeepBeep,ErlyWeb,Erlang Boss. 转自:http://bbs.chinaunix.net/thread-3764 ...

  10. 最有价值的50道java面试题 适用于准入职Java程序员

    下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最 ...