在实际项目中,我们通常会以Map的形式装载一些参数进行传参,而在一些特定的场合我们总是希望这些松散的属性能以java Bean的实体形式进行传递,于是,我们需要写很多相同的但又简单的不能再简单的语句重复一万遍.....例如:
<span style="white-space:pre"> </span>Map<String ,Object> map = new HashMap<String ,Object>();
map.put("status", ex1.getStatus());
map.put("gender", ex1.getGender());
map.put("age", ex1.getAge());
map.put("temp", ex1.getTemp());
map.put("name", ex1.getName());
这仅仅是5个属性,在实际情况中,随便的实体恐怕都有十几个属性,这样会有大量的冗余代码,鉴于Map这种松散的传参和Bean紧凑传参的方式不可避免而又各有优劣,我们有理由找到一个高效的方式使这两种结构无缝互转,我们知道Bean和Map的数据(逻辑)结构都相对简单,我们需要的仅仅是能获取到Bean的内部字段的名称和值,对应到Map的key-value即可,因此,Java的反射机制成了不二之选。废话少说,talk is cheap !show me the code!
package prs.rfh.test.flex;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @category Util
* @author renfh
* @since 2016-1-9
* @version 1.0
*/
public class TransBeanMapUtil {
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>private static Log log = LogFactory.getLog(TransBeanMapUtil.class);
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * trans elem from map to a bean
<span style="white-space:pre"> </span> * @param map
<span style="white-space:pre"> </span> * @param t Bean
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>public static <T extends Object,O> void transMapToBean(T t,Map<String ,Object> map){
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>if(t!=null&&map!=null){
<span style="white-space:pre"> </span>Class clazz = t.getClass();
<span style="white-space:pre"> </span>for(;clazz!=Object.class;clazz = clazz.getSuperclass()){
<span style="white-space:pre"> </span>Field [] fields = clazz.getDeclaredFields();
<span style="white-space:pre"> </span>for(int i=0 ;i<fields.length;i++){
<span style="white-space:pre"> </span>String name = fields[i].getName();
<span style="white-space:pre"> </span>Object value = map.get(name);
<span style="white-space:pre"> </span>fields[i].setAccessible(true);
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>fields[i].set(t,value);
<span style="white-space:pre"> </span>} catch (IllegalArgumentException e) {
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>} catch (IllegalAccessException e) {
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * trans entity from bean to a map
<span style="white-space:pre"> </span> * @param map
<span style="white-space:pre"> </span> * @param b Bean
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>public static <B extends Object> Map<String,Object> transBeanToMap( B b ){
<span style="white-space:pre"> </span>Class clazz = b.getClass();
<span style="white-space:pre"> </span>Map<String ,Object> map = new HashMap<String , Object>();
<span style="white-space:pre"> </span>if(b!=null){
<span style="white-space:pre"> </span>do {
<span style="white-space:pre"> </span>Field [] fields = clazz.getDeclaredFields();
<span style="white-space:pre"> </span>for(int i = 0 ;i < fields.length; i++){
<span style="white-space:pre"> </span>fields[i].setAccessible(true);
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>map.put(fields[i].getName(),fields[i].get(b));
<span style="white-space:pre"> </span>} catch (IllegalArgumentException e) {
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>} catch (IllegalAccessException e) {
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>clazz = clazz.getSuperclass();
<span style="white-space:pre"> </span>}while(clazz!=Object.class);
<span style="white-space:pre"> </span>}else if(log.isDebugEnabled()){
<span style="white-space:pre"> </span>log.debug("["+new Date()+"]"+TransBeanMapUtil.class+" occured a error while the bean is null");
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return map;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public static void main(String[] args) {
<span style="white-space:pre"> </span>Map<String ,Object> map = new HashMap<String ,Object>();
<span style="white-space:pre"> </span>map.put("status", 1);
<span style="white-space:pre"> </span>map.put("gender", "nan");
<span style="white-space:pre"> </span>map.put("age", "12");
<span style="white-space:pre"> </span>map.put("temp", "bad");
<span style="white-space:pre"> </span>map.put("name", "tom");
<span style="white-space:pre"> </span>Father tom = new Son();
<span style="white-space:pre"> </span>TransBeanMapUtil.transMapToBean(tom, map);
<span style="white-space:pre"> </span>System.out.println(map);
<span style="white-space:pre"> </span>Map<String ,Object> map_kate = TransBeanMapUtil.transBeanToMap(tom);
<span style="white-space:pre"> </span>System.out.println(map_kate);
<span style="white-space:pre"> </span>}
}
附具有继承关系的Bean实体类两个:
父类
package prs.rfh.test.flex;
public class Father {
private String name;
private String age;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
子类
package prs.rfh.test.flex;
public class Son extends Father {
private String status ;
private String temp;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
}
以上完成了一个简单的Map与Bean互转的Util工具类,可以实现对任何可见性的Bean及其父类的属性的值到Map的相互转换。由于只是实现了一个简单的功能,可能不够完善,不足之处还望指正,不胜感谢!