BeanUtils.copyProperties(target,source)和PropertyUtils.copyProperties(target,source)都能将源对象的属性的值拷贝到目标对象相同属性名中。
区别在于:
BeanUtils.copyProperties(target,source)
支持基础类型、String、java.sql.Date、java.sql.Timestamp、java.sql.Time之间的类型转换,即只要这些类型的属性名相同那么拷贝就能成功。但是会默认初始化属性值。注意:不支持java.util.Date类型的转化,需手动设置。
PropertyUtils.copyProperties(target,source)
不支持类型转换,但是不会初始话属性值,允许属性值为null。
在webservice中遇到了一个String类型,但是数据库是java.util.Date类型,因为对象属性不较多,所以在使用PropertyUtils.copyProperties(target,source)时报错。
后来查了下资料,说BeanUtils能进行类型转换,故而就自定义了一个String转Date的工具类。
定义工具类
package com.dhcc.phms.common.beanutils; import java.lang.reflect.InvocationTargetException; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.ConvertUtils; public class BeanUtilsEx extends BeanUtils{ static { //注册util.date的转换器,即允许BeanUtils.copyProperties时的源目标的util类型的值允许为空 ConvertUtils.register(new DateConvert(), java.util.Date.class); ConvertUtils.register(new DateConvert(), String.class); // BeanUtilsBean beanUtils = new BeanUtilsBean(ConvertUtils.class,new PropertyUtilsBean()); } public static void copyProperties(Object target, Object source) throws InvocationTargetException, IllegalAccessException { //支持对日期copy org.apache.commons.beanutils.BeanUtils.copyProperties(target, source); } }
定义日期转换格式
package com.dhcc.phms.common.beanutils; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.beanutils.Converter; 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]) ([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; } }
使用时用BeanUtilsEx. copyProperties(target,source)时即可实现String转换为Date。
除此之外,如果需要转换的属性比较少时,可先将source对象中冲突属性取出来,另存一份,然后将该属性值置为null,因为不会拷贝null属性,所以拷贝的时候不会出错。当拷贝完成后再将冲突属性转换为所需格式,set进目标对象。这样也是实现效果。
测试代码如下:
目标对象TargetObject
package test; import java.util.Date; public class TargetObject { Date date; Boolean isOther; public TargetObject(Date date,Boolean isOther) { super(); this.date = date; this.isOther = isOther; } public TargetObject() { super(); // TODO Auto-generated constructor stub } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Boolean getIsOther() { return isOther; } public void setIsOther(Boolean isOther) { this.isOther = isOther; } @Override public String toString() { return "TargetObject [date=" + date + ", isOther=" + isOther + "]"; } }
源对象SourceObject
package test; public class SourceObject { String date; String other; public SourceObject(String date,String other) { super(); this.date = date; this.other = other; } public SourceObject() { super(); // TODO Auto-generated constructor stub } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getOther() { return other; } public void setOther(String other) { this.other = other; } @Override public String toString() { return "SourceObject [date=" + date + ", other=" + other + "]"; } }
测试代码
public static void main(String[] args) { SourceObject source = new SourceObject("2017-07-17","false"); TargetObject target = new TargetObject(); try { BeanUtilsEx.copyProperties(target,source); System.out.println(source.toString());//SourceObject [date=2017-07-17, other=false] System.out.println(target.toString());//TargetObject [date=Mon Jul 17 00:00:00 CST 2017, isOther=null] if(source.getOther().equals("true")) {//对于属性名不一样的属性是不会赋值的,需要手动设置 target.setIsOther(true); }else { target.setIsOther(false); } } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
BeanUtils.copyProperties 日期转字符 日期转Long
建立自己的日期转换类
import org.apache.commons.beanutils.ConversionException; import org.apache.commons.beanutils.Converter; import org.apache.commons.lang.time.DateUtils; public class DateConverter implements Converter { private static final SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override public Object convert(Class type, 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()); } try { return dateFormat.parse(value.toString()); //return DateUtils.parseDate(value.toString(), new String[] {"yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd HH:mm:ss","yyyy-MM-dd HH:mm" }); } catch (Exception e) { throw new ConversionException(e); } } }
使用自己的日期转换类替代默认的。如下面的main函数
public static void main(String[] args) { //替换 ConvertUtils.register(new DateConverter(), Date.class); //ConvertUtils.register(new StringConverter(), String.class); A a = new A(); a.date="2012-03-14 17:22:16"; B b = new B(); try { BeanUtils.copyProperties(b, a); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(b.getDate()); }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。