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);
}
}
}
}
}
}
}