BeanUtils.copyProperties支持Date类型

本文介绍了一个扩展的BeanUtils类,该类增加了对日期类型的转换支持,通过自定义的日期转换器,使得Bean属性复制时能更好地处理日期格式。
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.log4j.Logger;

/**
 * @Title 扩展BeanUtils.copyProperties支持data类型
 * @Description
 * @author wangzs
 * @date 2017-1-5
 */
public class BeanUtilsEx extends BeanUtils {
	private static Logger logger = Logger.getLogger(BeanUtilsEx.class);

	static {
		ConvertUtils.register(new DateConvert(), java.util.Date.class);
		ConvertUtils.register(new DateConvert(), String.class);
	}

	public static void copyProperties(Object target, Object source) {
		// 支持对日期copy
		try {
			org.apache.commons.beanutils.BeanUtils.copyProperties(target, source);
		} catch (IllegalAccessException | InvocationTargetException e) {
			logger.error("扩展BeanUtils.copyProperties支持data类型:" + e.getMessage());
			e.printStackTrace();
		}
	}
}


import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.beanutils.Converter;

/**
 * @Title 扩展BeanUtils.copyProperties支持data类型
 * @Description
 * @author wangzs
 * @date 2017-1-5
 */
public class DateConvert implements Converter {
	@Override
	public Object convert(Class class1, Object value) {
		if (value == null) {
			return null;
		}
		if (value instanceof Date) {
			return value;
		}
		if (value instanceof Long) {
			Long longValue = (Long) value;
			return new Date(longValue.longValue());
		}
		if (value instanceof String) {
			String dateStr = (String) value;
			Date endTime = null;
			try {
				String regexp1 = "([0-9]{4})-([0-1][0-9])-([0-3][0-9])T([0-2][0-9]):([0-6][0-9]):([0-6][0-9])";
				String regexp2 = "([0-9]{4})-([0-1][0-9])-([0-3][0-9])(/t)([0-2][0-9]):([0-6][0-9]):([0-6][0-9])";
				String regexp3 = "([0-9]{4})-([0-1][0-9])-([0-3][0-9])";
				if (dateStr.matches(regexp1)) {
					dateStr = dateStr.split("T")[0] + " " + dateStr.split("T")[1];
					DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					endTime = sdf.parse(dateStr);
					return endTime;
				} else if (dateStr.matches(regexp2)) {
					DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					endTime = sdf.parse(dateStr);
					return endTime;
				} else if (dateStr.matches(regexp3)) {
					DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					endTime = sdf.parse(dateStr);
					return endTime;
				} else {
					return dateStr;
				}
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return value;
	}
}


### 关于 `BeanUtils.copyProperties` 方法对 `Date` 和 `BigDecimal` 类型支持 #### 1. **关于 `BeanUtils.copyProperties` 的行为** `BeanUtils.copyProperties` 是 Apache Commons BeanUtils 提供的一个工具方法,用于将源对象中的属性值复制到目标对象中。如果源对象和目标对象具有相同的属性名称,则该方法会尝试将这些属性的值从源对象复制到目标对象。 对于不同类型的属性(如 `String` 转换为 `BigDecimal` 或者 `Date`),`BeanUtils.copyProperties` 默认情况下不支持自动类型转换[^1]。这意味着当遇到类型不匹配的情况时,它可能会抛出异常或者忽略这些字段而不执行任何操作。 --- #### 2. **针对 `Date` 类型的行为** `BeanUtils.copyProperties` 可以处理基本的对象引用赋值,因此如果源对象和目标对象都定义了一个名为 `dateField` 的属性,并且它们都是 `java.util.Date` 类型或其子类(例如 `Timestamp`),那么它可以正常工作并完成复制: ```java @Data public class Source { private Date date; } @Data public class Target { private Date date; } ``` 在这种场景下,假设 `Source.date` 已经被初始化,调用如下代码可以成功复制日期值: ```java Source source = new Source(); source.setDate(new Date()); Target target = new Target(); BeanUtils.copyProperties(source, target); System.out.println(target.getDate()); ``` 然而需要注意的是,这种复制实际上是浅拷贝 (shallow copy),即只是简单地将源对象中的引用传递给目标对象。修改其中一个对象的 `date` 属性会影响另一个对象的状态[^4]。 --- #### 3. **针对 `BigDecimal` 类型的行为** 由于 `BeanUtils.copyProperties` 不具备内置的类型转换能力,因此在涉及 `BigDecimal` 和其他类型之间的转换时会出现问题。例如,考虑以下情况: ```java @Data public class Source { private String value; // 假设这是一个字符串表示的小数 } @Data public class Target { private BigDecimal value; } ``` 此时运行下面的代码将会失败,因为 `BeanUtils.copyProperties` 尝试直接将 `String` 类型赋值给 `BigDecimal` 类型,这会导致类型不兼容错误: ```java Source source = new Source(); source.setValue("10.5"); Target target = new Target(); try { BeanUtils.copyProperties(source, target); } catch (Exception e) { System.err.println(e.getMessage()); } ``` 为了实现这样的类型转换,可能需要手动编写逻辑来预处理数据或将自定义转换器集成到流程中[^3]。 --- #### 4. **对比 `PropertyUtils.copyProperties`** 相比之下,`PropertyUtils.copyProperties` 更加严格——即使面对完全一致的数据结构也不会试图进行任何形式的隐式类型转换。换句话说,只有当源属性与目标属性不仅名字相同而且确切无误地属于同一 Java 数据类型时才会发生实际的数据迁移过程[^2]。 --- ### 总结 - 对于 `Date` 类型,只要源和目标字段均为 `Date` 或其派生类实例,`BeanUtils.copyProperties` 即可顺利完成复制任务。 - 针对 `BigDecimal` 类型而言,除非两者均声明为此种数值类别之外,否则因缺乏必要的转型机制而导致不可预期的结果甚至程序崩溃的风险较高。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值