BeanUtil - Bean的操作

1、所谓Bean就是指包含一个或多个属性,并可以用get/set方法取/存数据的类。 map也可以看成是Bean的一种。这个类提供了bean之间复制数据、将Map中数据设定到实体对象bean中、取得bean的所有属性、
判断bean中是否有属性等方法。

package com.ilogie.core.util;

  
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.beanutils.PropertyUtils;

/**
 * 
 * bean转换工具类
 * 
 * Description:提供了bean操作的一系列方法。所谓Bean就是指包含一个或多个属性,并可以用get/set方法取/存数据的类。 map也可以看成是Bean的一种。
 * 这个类提供了bean之间复制数据、取得bean的所有属性、判断bean中是否有属性等方法。
 *
 * @version 1.0
 */
public abstract class BeanUtil {


	/**
	 * 将源对象的所有属性值复制到目标对象
	 *
	 * @param to 目标拷贝对象,该对象不能为map
	 * @param from 拷贝源
	 */
	public static Object copy(Object to, Object from) {
		try {
			PropertyUtils.copyProperties(to, from);
			return to;
		}
		catch (IllegalAccessException e) {
			throw new RuntimeException("拷贝时出错,用反射机制时属性或者方法不能被访问。", e);
		}
		catch (InvocationTargetException e) {
			throw new RuntimeException("拷贝时出错,用反射机制调用方法时。", e);
		}
		catch (NoSuchMethodException e) {
			throw new RuntimeException("拷贝时出错,用反射机制调用方法时方法不存在。", e);
		}
	}

	/**
	 * <p>
	 * 将源对象的所有属性值复制到目标对象,但是忽略ignore中含有的属性
	 * </p>
	 *
	 * @param to 目标拷贝对象
	 * @param from 拷贝源
	 * @param ignore 需要忽略的属性
	 */
	public static Object copy(Object to, Object from, String[] ignore) {

		List list = null;
		if (ignore == null) {
			list = new ArrayList();
		}
		else {
			list = Arrays.asList(ignore);
		}
		PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(to);
		for (int i = 0; i < descr.length; i++) {
			PropertyDescriptor d = descr[i];
			if (d.getWriteMethod() == null)
				continue;
			if (list.contains(d.getName()))
				continue;
			try {
				Object value = PropertyUtils.getProperty(from, d.getName());
				PropertyUtils.setProperty(to, d.getName(), value);
			}
			catch (Exception e) {
				throw new RuntimeException("属性名:" + d.getName() + " 在实体间拷贝时出错", e);
			}
		}
		return to;
	}

	/**
	 * <p>
	 * 根据属性名称和属性值,将数据设定到实体对象bean中
	 * </p>
	 *
	 * @param bean 对象,可以为map
	 * @param propertyName 属性名称
	 * @param value 属性值
	 */
	public static Object setDataToBean(Object bean, String propertyName, Object value) {
		try {
			PropertyUtils.setProperty(bean, propertyName, value);
		}
		catch (IllegalAccessException e) {
			throw new RuntimeException("没有权限访问相应属性:" + propertyName, e);
		}
		catch (InvocationTargetException e) {
			throw new RuntimeException("访问属性:" + propertyName + "时出错", e);
		}
		catch (NoSuchMethodException e) {
			throw new RuntimeException("属性:" + propertyName + "没有相应的SET方法", e);
		}
		return bean;
	}

	/**
	 * 
	 * @param bean
	 * @param property
	 * @param value
	 * @param ignorePrefix
	 * @return
	 */
	public static Object setDataToBean(Object bean, String property,
			Object value, boolean ignorePrefix) {

		PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(bean);
		for (int i = 0; i < descr.length; i++) {
			PropertyDescriptor d = descr[i];

			String name = d.getName();

			if (ignorePrefix) {
				name = name.substring(1);
			}

			if (d.getWriteMethod() == null) // 如果当前属性没有对应的可写的方法,则跳过到下一属性
				continue;
			if (property.equals(name)) // 如果Map的key值中无当前属性值,则跳过到下一属性
				try {
					Class clazz = d.getPropertyType();
					if (value == null) {
						PropertyUtils.setProperty(bean, d.getName(), null);
						continue;
					}
					/*
					 * 如果属性的类型不是java.lang.String且值为空,则不将map中该属性的值设置到实体中,
					 * 防止象Long型的guId,如果为空则值为null setProperty(....)会出错
					 */
					if ((String.class != clazz && "".equals(value))
							|| value == null) {
						continue;
					}
					if (Date.class == clazz && String.class == value.getClass()) {
						value = DateUtil.parseDate((String) value);
						// value = ((String)value).replace('-', '/');
						// //日期类型的2006-5-12转换成2006/5/12
					}
					if (Long.class == clazz) {
						value = new Long(value.toString());
					}
					if (Boolean.class == clazz) {
						if ("0".equals(value)) {
							value = false;
						} else {
							value = true;
						}
					}
					// 转换数字
					if (BigDecimal.class == clazz
							&& (Double.class == value.getClass()
									|| Integer.class == value.getClass()
									|| Long.class == value.getClass() || Float.class == value
									.getClass())) {
						value = new BigDecimal(value + "");
					}
					if (clazz == value.getClass()) { // value一般为前台传入,类型多为String型
						PropertyUtils.setProperty(bean, d.getName(), value);
					} else {
						if (clazz == BigDecimal.class || clazz == Double.class) {
							value = value.toString().replaceAll(",", "");
						}
						PropertyUtils
								.setProperty(
										bean,
										d.getName(),
										clazz.getConstructor(
												new Class[] { String.class })
												.newInstance(
														new Object[] { value
																.toString() }));
					}
				} catch (Exception e) {
					throw new RuntimeException("属性名:" + d.getName()
							+ " 设置到实体中时出错", e);
				}
		}
		return bean;
	}
	
	/**
	 * 
	 * @param bean
	 * @param map
	 * @param ignorePrefix
	 * @param ignore
	 * @return
	 */
	public static Object setDataToBean(Object bean, Map map, boolean ignorePrefix,String [] ignore) {
		List list = null;
		if (ignore == null) {
			list = new ArrayList();
		}
		else {
			list = Arrays.asList(ignore);
		}
		
		PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(bean);
		for (int i = 0; i < descr.length; i++) {
			PropertyDescriptor d = descr[i];

			String name = d.getName();

			if (ignorePrefix) {
				name = name.substring(1);
			}
			if (list.contains(name)){
				continue;
			}
			if (d.getWriteMethod() == null) // 如果当前属性没有对应的可写的方法,则跳过到下一属性
				continue;
			if (!map.containsKey(name)) // 如果Map的key值中无当前属性值,则跳过到下一属性
				continue;
			try {
				Class clazz = d.getPropertyType();
				Object value = map.get(name);
				if (value == null) {
					PropertyUtils.setProperty(bean, d.getName(), null);
					continue;
				}
				/*
				 * 如果属性的类型不是java.lang.String且值为空,则不将map中该属性的值设置到实体中, 防止象Long型的guId,如果为空则值为null
				 * setProperty(....)会出错
				 */
				if ((String.class != clazz && "".equals(value)) || value == null) {
					continue;
				}
				if (Date.class == clazz && String.class == value.getClass()) {
					value = DateUtil.parseDate((String) value);
					// value = ((String)value).replace('-', '/');
					// //日期类型的2006-5-12转换成2006/5/12
				}
				if (Long.class == clazz) {
					try{
						value = new Long(value.toString());
					}catch(Exception e){
						value = 0l;
					}
					
				}
				if (Boolean.class == clazz) {
					if ("0".equals(value)) {
						value = false;
					}
					else {
						value = true;
					}
				}
				//转换数字
				if (BigDecimal.class == clazz
						&& (Double.class == value.getClass() || Integer.class == value.getClass()
								|| Long.class == value.getClass() || Float.class == value
								.getClass())) {
					value = new BigDecimal(value + "");
				}
				if (clazz == value.getClass()) { // value一般为前台传入,类型多为String型
					PropertyUtils.setProperty(bean, d.getName(), value);
				}
				else {
					if(clazz == BigDecimal.class || clazz == Double.class){
						value = value.toString().replaceAll(",", "");
					}
					try{
					PropertyUtils.setProperty(
							bean,
							d.getName(),
							clazz.getConstructor(new Class[] { String.class }).newInstance(
									new Object[] { value.toString() }));
					}catch(Exception e){
					}
				}
			}
			catch (Exception e) {
				throw new RuntimeException("属性名:" + d.getName() + " 设置到实体中时出错", e);
			}
		}
		return bean;
	}
	/**
	 *
	 * 按照Map中的key和bean中的属性名一一对应,将Map中数据设定到实体对象bean中 如果map中的属性没有前缀(前缀指的是数据库中的字段类型,如c,f等),要复制到
	 * bean中去的时候,ignorePrefix需要设置成true
	 *
	 * @param bean
	 * @param attrsMap
	 * @param ignorePrefix 是否忽略属性名称前缀
	 *
	 */
	public static Object setDataToBean(Object bean, Map map, boolean ignorePrefix) {
		return setDataToBean(bean, map, ignorePrefix,null);
	}

	/**
	 * 按照Map中的key和bean中的属性名一一对应,将Map中数据设定到实体对象bean中
	 *
	 * @param bean
	 * @param attrsMap
	 */
	public static Object setDataToBean(Object bean, Map map) {
		return setDataToBean(bean, map, false);
	}
	/**
	 * 按照Map中的key和bean中的属性名一一对应,将Map中数据设定到实体对象bean中
	 * 排除掉默认为0 的值,修改为空,
	 * 仅适用于修改操作。
	 * @param bean
	 * @param map
	 * @return  
	 * @since 1.0
	 */
	public static Object setDataToBeanWithoutZero(Object bean,Map map){
	    Map<String,Object> proMap = BeanUtil.getProperties(bean);
	    for(Entry<String,Object> entry : proMap.entrySet()){
	        if(String.valueOf(entry.getValue()).equals("0")){
	            entry.setValue(null);
	        } 
	    }
	    proMap.putAll(map);
	    return setDataToBean(bean,proMap);
	}

	/**
	 * <p>
	 * 获取实体对象的所有属性
	 * </p>
	 *
	 * @param bean 实体对象
	 * @return Map 属性集合
	 */
	public static Map getProperties(Object bean) {
	    //设置忽略属性 class
        Set<String>  ignores= new HashSet<String>();
        ignores.add("class");  
		return getProperties(bean, ignores);
	}

	/**
	 * <p>
	 * 获取实体对象的某些属性
	 * </p>
	 *
	 * @param bean 实体对象
	 * @param ignores Set 忽略的属性名集合
	 * @return Map 属性集合
	 */
	public static Map getProperties(Object bean, Set ignores) {
		Map map = new HashMap();
		PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(bean);
		for (int i = 0; i < descr.length; i++) {
			PropertyDescriptor d = descr[i];
			if (d.getReadMethod() == null) // 如果当前属性没有对应的可读的方法,则跳过
				continue;
			String name = d.getName();
			if (ignores.contains(name)) // 如果为忽略处理属性,则跳过
				continue;
			map.put(name, getPropertyValueByName(bean, name));
		}
		return map;
	}

	/**
	 * 获取对象中指定属性的值
	 *
	 * @param obj
	 * @param name
	 * @return
	 */
	public static Object getPropertyValueByName(Object bean, String propertyName) {
		try {
			  Object obj = PropertyUtils.getProperty(bean, propertyName);
			  if(obj != null ){
			      obj = obj.toString();
			  }
			  return obj;
		}
		catch (IllegalAccessException e) {
			throw new RuntimeException("没有权限访问相应属性:" + propertyName, e);
		}
		catch (InvocationTargetException e) {
			throw new RuntimeException("访问属性:" + propertyName + "时出错", e);
		}
		catch (NoSuchMethodException e) {
			throw new RuntimeException("属性:" + propertyName + "没有相应的GET方法", e);
		}
	}

	/**
	 * 判断属性是否在实体中。对于map,要使用isContains()方法,而不是此方法
	 *
	 * @param bean
	 * @param propertyName
	 * @return
	 */
	public static boolean isPropertyInBean(Object bean, String propertyName) {
		PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(bean);
		for (int i = 0; i < descr.length; i++) {
			PropertyDescriptor d = descr[i];
			if (propertyName.equals(d.getName())) {
				return true;
			}
		}
		return false;
	}

	
	/**
	 * 对象属性复制工具
	 * @param to
	 * @param from
	 */
	public static Object copyWithoutNull(Object to, Object from) {
		return copyWithoutNull(to,from,null);
	}
	
	/**
	 * 对象属性复制工具
	 *
	 * @param to 目标拷贝对象
	 * @param from 拷贝源
	 * @param ignore 需要忽略的属性
	 */
	public static Object copyWithoutNull(Object to, Object from, String[] ignore) {

		List list = new ArrayList();
		if (ignore != null) {
			list = Arrays.asList(ignore);
		}
		PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(to);
		for (int i = 0; i < descr.length; i++) {
			PropertyDescriptor d = descr[i];
			if (d.getWriteMethod() == null)
				continue;
			if (list.contains(d.getName()))
				continue;
			try {
				Object value = PropertyUtils.getProperty(from, d.getName());
				if (value != null )
					PropertyUtils.setProperty(to, d.getName(), value);
			}
			catch (Exception e) {
				throw new RuntimeException("属性名:" + d.getName() + " 在实体间拷贝时出错", e);
			}
		}
		return to;
	}

 
}

2、对于复制数据的方法,也可以参照修改org.springframework.beans.BeanUtils类中的部分代码

package com.ilogie.core.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

public abstract class BeanUtils extends org.springframework.beans.BeanUtils{
    
    /** 
     * 从org.springframework.beans.BeanUtils类中直接复制过来 
     * @param source 
     * @param target 
     * @throws BeansException 
     */  
    public static void copyProperties(Object source, Object target) throws BeansException {  
        copyProperties(source, target, null, (String[]) null);  
    }  
    
    /** 
     * 从org.springframework.beans.BeanUtils类中直接复制过来,修改部分代码 
     * @param source 
     * @param target 
     * @param editable 
     * @param ignoreProperties 
     * @throws BeansException 
     */  
    private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)  
            throws BeansException {  
  
        Assert.notNull(source, "Source must not be null");  
        Assert.notNull(target, "Target must not be null");  
  
        Class<?> actualEditable = target.getClass();  
        if (editable != null) {  
            if (!editable.isInstance(target)) {  
                throw new IllegalArgumentException("Target class [" + target.getClass().getName() +  
                        "] not assignable to Editable class [" + editable.getName() + "]");  
            }  
            actualEditable = editable;  
        }  
        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);  
        List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;  
  
        for (PropertyDescriptor targetPd : targetPds) {  
            Method writeMethod = targetPd.getWriteMethod();  
            if (writeMethod != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {  
                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());  
                if (sourcePd != null) {  
                    Method readMethod = sourcePd.getReadMethod();  
                    if (readMethod != null &&  
                            ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {  
                        try {  
                            if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {  
                                readMethod.setAccessible(true);  
                            }  
                            Object value = readMethod.invoke(source);  
                            // 判断被复制的属性是否为null, 如果不为null才复制  
                            if (value != null && !"".equals(value)) {  
                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {  
                                    writeMethod.setAccessible(true);  
                                }  
                                writeMethod.invoke(target, value);  
                            }  
                        }  
                        catch (Throwable ex) {  
                            throw new FatalBeanException(  
                                    "Could not copy property '" + targetPd.getName() + "' from source to target", ex);  
                        }  
                    }  
                }  
            }  
        }  
    }  

}

猜你喜欢

转载自my.oschina.net/u/3496297/blog/1596406