一、 简介
BeanUtils提供对Java反射和自省API的包装。其主要目的是利用反射机制对JavaBean的属性进行简化操作处理。一个JavaBean通常包含了大量的属性,很多情况下,对JavaBean的处理导致大量get/set代码堆积,增加了代码长度和阅读代码的难度。
二、 使用BeanUtils组件
(1) 创建java项目,新建名为f.b.y.beans以及新建f.b.y.beans.test包
(2)Person.java


1 package f.b.y.beans; 2 3 public class Person { 4 5 String name; 6 7 String sex; 8 9 String address; 10 11 int age; 12 13 public Person() { 14 15 super(); 16 17 } 18 19 public String getName() { 20 21 return name; 22 23 } 24 25 public void setName(String name) { 26 27 this.name = name; 28 29 } 30 31 public String getSex() { 32 33 return sex; 34 35 } 36 37 public void setSex(String sex) { 38 39 this.sex = sex; 40 41 } 42 43 public String getAddress() { 44 45 return address; 46 47 } 48 49 public void setAddress(String address) { 50 51 this.address = address; 52 53 } 54 55 public int getAge() { 56 57 return age; 58 59 } 60 61 public void setAge(int age) { 62 63 this.age = age; 64 65 } 66 67 @Override 68 69 public String toString() { 70 71 return "Person [name=" + name + ", sex=" + sex + ", address=" + address + ", age=" + age + "]"; 72 73 } 74 75 }
(3)导入相关的jar包
1.引入commons-beanutils-1.8.3.jar核心包
2.引入日志支持包: commons-logging-1.1.3.jar
如果缺少日志jar文件,报错:
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.apache.commons.beanutils.ConvertUtilsBean.<init>(ConvertUtilsBean.java:157)
at org.apache.commons.beanutils.BeanUtilsBean.<init>(BeanUtilsBean.java:117)
at org.apache.commons.beanutils.BeanUtilsBean$1.initialValue(BeanUtilsBean.java:68)
at org.apache.commons.beanutils.ContextClassLoaderLocal.get(ContextClassLoaderLocal.java:153)
(4) PersonTest.java


1 public class PersonTest { 2 3 @Test 4 5 public void test1 () throws Exception{ 6 7 //1.基本操作对bean赋值取值 8 9 Person person = new Person(); 10 11 person.setName("Mike"); 12 13 person.setAge(22); 14 15 System.out.println(person.getName()); 16 17 System.out.println(person.getAge()); 18 19 //如果有很多属性要赋值,一个个去赋值很麻烦 20 21 //2.使用BeanUtils组件 22 23 //2.1导包 24 25 /* 26 27 * 新建lib文件夹,导入commons-beanutils-1.8.3.jar(BeanUtils包)、 28 29 * commons-logging-1.1.3.jar(日志包)并将添加至构建路径 30 31 */ 32 33 //2.2对象属性拷贝 34 35 //BeanUtils.copyProperty(bean, name, value);对象属性赋值,bean对象,属性名,属性值 36 37 BeanUtils.copyProperty(person, "address", "HeYuan");//属性名要与bean属性名一致 38 39 System.out.println(person.getAddress()); 40 41 //2.3对象的拷贝 42 43 //BeanUtils.copyProperties(dest, orig);dest是目标bean对象,orig是源bean对象 44 45 Person dest = new Person(); 46 47 BeanUtils.copyProperties(dest, person); 48 49 System.out.println(dest.getName()); 50 51 //2.4map的数据拷贝到javabean中 52 53 /* 54 55 * BeanUtils.populate(bean, properties);bean是bean对象,properties是键值对 56 57 */ 58 59 Map<String, Object> map = new HashMap<String, Object>(); 60 61 map.put("name", "joe"); 62 63 map.put("age", 23); 64 65 Person personmap = new Person(); 66 67 BeanUtils.populate(personmap , map); 68 69 System.out.println(personmap .getName()); 70 71 System.out.println(personmap .getAge()); 72 73 } 74 75 }
总结:
1. 对象属性拷贝
BeanUtils.copyProperty(bean, name, value);//,bean对象,属性名,属性值。
BeanUtils.setProperty(bean, name, value);
2. BeanUtils.copyProperties(dest, orig);dest是目标bean对象,orig是源bean对象
3. map的数据拷贝到javabean中
BeanUtils.populate(bean, properties);bean是bean对象,properties是键值对
4. BeanUtils在对Bean赋值是会进行类型转化
三、 日期类型转换
BeanUtils支持的转换类型如下:
* java.lang.BigDecimal
* java.lang.BigInteger
* boolean and java.lang.Boolean
* byte and java.lang.Byte
* char and java.lang.Character
* java.lang.Class
* double and java.lang.Double
* float and java.lang.Float
* int and java.lang.Integer
* long and java.lang.Long
* short and java.lang.Short
* java.lang.String
* java.sql.Date
* java.sql.Time
* java.sql.Timestamp
这里要注意一点,java.util.Date是不被支持的,而它的子类java.sql.Date是被支持的。因此如果对象包含时间类型的属性,且希望被转换的时候,一定要使用java.sql.Date类型。否则在转换时会提示argument mistype异常。
(1)Person2.java(注意java.util.Date,新增加Date birthday)


1 import java.util.Date; 2 3 public class Person2 { 4 5 String name; 6 7 String sex; 8 9 String address; 10 11 int age; 12 13 Date birthday; 14 15 public Date getBirthday() { 16 17 return birthday; 18 19 } 20 21 public void setBirthday(Date birthday) { 22 23 this.birthday = birthday; 24 25 } 26 27 public Person2() { 28 29 super(); 30 31 } 32 33 public String getName() { 34 35 return name; 36 37 } 38 39 public void setName(String name) { 40 41 this.name = name; 42 43 } 44 45 public String getSex() { 46 47 return sex; 48 49 } 50 51 public void setSex(String sex) { 52 53 this.sex = sex; 54 55 } 56 57 public String getAddress() { 58 59 return address; 60 61 } 62 63 public void setAddress(String address) { 64 65 this.address = address; 66 67 } 68 69 public int getAge() { 70 71 return age; 72 73 } 74 75 public void setAge(int age) { 76 77 this.age = age; 78 79 } 80 81 @Override 82 83 public String toString() { 84 85 return "Person2 [name=" + name + ", sex=" + sex + ", address=" + address + ", age=" + age + ", birthday=" 86 87 + birthday + "]"; 88 89 } 90 91 } 92 93 (2) PersonTest.java 94 95 public class PersonTest { 96 97 @Test 98 99 public void test2 () throws Exception{ 100 101 //模拟表单数据 102 103 String name = "mokey"; 104 105 String age = "22"; 106 107 String birthday ="1993-01-5"; 108 109 //对象 110 111 Person2 person2 = new Person2(); 112 113 //把表单提交的数据,封装到对象中 114 115 BeanUtils.copyProperty(person2, "name", name); 116 117 BeanUtils.copyProperty(person2, "age", age); 118 119 BeanUtils.copyProperty(person2, "birthday", birthday); 120 121 System.out.println(person2); 122 123 } 124 125 }
报错:使用BeanUtils时,Date类型值为空,BeanUtils不支持Date日期转换。
org.apache.commons.beanutils.ConversionException: DateConverter does not support default String to 'Date' conversion.
3.1日期类型修改为java.sql.Date
解决方法之一: 在bean中修改日期类型改为:import java.sql.Date;
(1)Person2.java


1 import java.sql.Date; 2 3 public class Person2 { 4 5 String name; 6 7 String sex; 8 9 String address; 10 11 int age; 12 13 Date birthday; 14 15 public Date getBirthday() { 16 17 return birthday; 18 19 } 20 21 public void setBirthday(Date birthday) { 22 23 this.birthday = birthday; 24 25 } 26 27 public Person2() { 28 29 super(); 30 31 } 32 33 public String getName() { 34 35 return name; 36 37 } 38 39 public void setName(String name) { 40 41 this.name = name; 42 43 } 44 45 public String getSex() { 46 47 return sex; 48 49 } 50 51 public void setSex(String sex) { 52 53 this.sex = sex; 54 55 } 56 57 public String getAddress() { 58 59 return address; 60 61 } 62 63 public void setAddress(String address) { 64 65 this.address = address; 66 67 } 68 69 public int getAge() { 70 71 return age; 72 73 } 74 75 public void setAge(int age) { 76 77 this.age = age; 78 79 } 80 81 @Override 82 83 public String toString() { 84 85 return "Person2 [name=" + name + ", sex=" + sex + ", address=" + address + ", age=" + age + ", birthday=" 86 87 + birthday + "]"; 88 89 } 90 91 }
(2) test2


1 @Test 2 3 public void test2 () throws Exception{ 4 5 //模拟表单数据 6 7 String name = "Hide"; 8 9 String birthday ="1993-01-5"; 10 11 //对象 12 13 Person2 person2 = new Person2(); 14 15 //把表单提交的数据,封装到对象中 16 17 BeanUtils.copyProperty(person2, "name", name); 18 19 BeanUtils.copyProperty(person2, "birthday", birthday); 20 21 System.out.println(person2.getName()); 22 23 System.out.println(person2.getBirthday()); 24 25 } 26 27 输出结果: 28 29 clip_image012 30 31 3.2使用日期转换器工具类 32 33 (1)Person3.java 34 35 import java.util.Date; 36 37 public class Person3 { 38 39 String name; 40 41 String sex; 42 43 String address; 44 45 int age; 46 47 Date birthday; 48 49 public Date getBirthday() { 50 51 return birthday; 52 53 } 54 55 public void setBirthday(Date birthday) { 56 57 this.birthday = birthday; 58 59 } 60 61 public Person3() { 62 63 super(); 64 65 } 66 67 public String getName() { 68 69 return name; 70 71 } 72 73 public void setName(String name) { 74 75 this.name = name; 76 77 } 78 79 public String getSex() { 80 81 return sex; 82 83 } 84 85 public void setSex(String sex) { 86 87 this.sex = sex; 88 89 } 90 91 public String getAddress() { 92 93 return address; 94 95 } 96 97 public void setAddress(String address) { 98 99 this.address = address; 100 101 } 102 103 public int getAge() { 104 105 return age; 106 107 } 108 109 public void setAge(int age) { 110 111 this.age = age; 112 113 } 114 115 @Override 116 117 public String toString() { 118 119 return "Person2 [name=" + name + ", sex=" + sex + ", address=" + address + ", age=" + age + ", birthday=" 120 121 + birthday + "]"; 122 123 } 124 125 }
(2) test3


@Test public void test3 () throws Exception{ //模拟表单数据 String name = "Hide"; String sex="男"; String address= "heyuan"; int age = 21; String birthday ="1993-01-5"; //对象 Person2 person2 = new Person2(); // 注册sql.date的转换器,即允许BeanUtils.copyProperty时的源目标的sql类型的值允许为空 ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.sql.Date.class); ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.util.Date.class); ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlTimestampConverter(null), java.sql.Timestamp.class); //把表单提交的数据,封装到对象中 BeanUtils.copyProperty(person2, "name", name); BeanUtils.copyProperty(person2, "sex", sex); BeanUtils.copyProperty(person2, "address", address); BeanUtils.copyProperty(person2, "age", age); BeanUtils.copyProperty(person2, "birthday", birthday); //测试 System.out.println(person2); //输出Person2 [name=Hide, sex=男, address=heyuan, age=21, birthday=1993-01-05] }
小结:
1.日期类型选择java.util.Date
2.可在类中初始化日期转换器


1 static{ 2 3 ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.sql.Date.class); 4 5 ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.util.Date.class); 6 7 ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlTimestampConverter(null), java.sql.Timestamp.class); 8 9 }
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp区别和总结
http://www.iteye.com/topic/1137830
在web开发中,避免不了对日期的操作,常见的日期操作做个总结:
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp
java.lang.Object
....|__java.util.Date
..........|__java.sql.Date/java.sql.Timestamp /java.sql.Time
....|__java.security.Timestamp
java.util.Date日期格式为:年月日时分秒
java.sql.Date日期格式为:年月日[只存储日期数据不存储时间数据]
java.sql.Time日期格式为:时分秒
java.sql.Timestamp日期格式为:年月日时分秒纳秒(毫微秒)
关系:
java.util.Date这个类是java.sql.Date, java.sql.Time, java.slq.Timestamp这三个类的父类。这三个类对java.util.Date类进行了包装。
联系:
java.sql.Date类屏蔽了java.util.Date类的时间有关的方法(形如:hh:mm:ss),因此,不可以通过这个类访问时间有关的信息,比如,如果你通过sqlDate.getHour()方法去访问小时信息,此方法会抛出一个IllegalArgumentException异常。这是因为java.sql.Date在继承java.util.Date类的时候对父类进行了重写,禁用了时间访问的方法。之所以这么处理,是为了和数据库的Date数据类型相匹配,数据库的Date数据类行只是保存日期有关的字段。
Java.sql.Time类屏蔽了java.util.Date的日期有关的字段(形如:yyyy-MM-dd),因此,不能通过这个类访问日期有关的信息,比如:如果你通过sqlTime.getYear()方法去获取年有关的信息,此方法会抛出一个IllegalArgumentException异常。这是因为java.sql.Time在继承java.util.Date类的时候对父类进行了重写,禁用了日期访问的方法。之所以这么处理,是为了和数据库的Time数据类型相匹配,数据库的Time数据类行只是保存时间有关的字段。
Java.sql.Timestamp字段则对java.util.Date这个类进行了扩充,它在java.util.Date类的基础上增加了毫秒的时间访问控制,因此,你可以通过getNanos()方法去获取时间的毫微秒数(注意此处获取的时间是以毫微秒为单位的,1秒等于十亿毫微秒),同样的,这也是为了和数据库中的Timestamp数据类型进行匹配。
理清了上述四个类的关系,那么java.util.Date和java.util.Calendar类有什么关系呢?
Java.util.Calendar类是java.util.Date类的一个更加深入,更加全面的替代。Java.util.Calendar类支持java.util.Date的所有功能,此外,Calendar还引入了多语言,多区域的特性,可以根据需要获取不同区域,不同时区的时间,Calendar还增加了比Date更加方便和快捷的许多操作,如获取一年当中的第几个星期,各个月的天数等便捷的方法。
注意:
Java.util.Calendar区别与java.util.Date的几个地方也需要注意一下:首先,Calendar增加了毫秒的时间段,通过它可以获取时间点的毫秒值,而java.util.Date只是精确到秒。其次,Calendar过去年的时候是当前年份比如:2010,而Date获取年份的时获取到的是当前年份-1900的一个值(2010-1900=110,因此,你调用getYear后过去的值就是110)。最后Calendar是一个抽象类,之所以能够实例化,是因为此处的Calendar充当了一个类似于工厂的作用,在getInstance方法中实例化了Calendar子类GregorianCalendar,并把它返回给用户使用。
针对不同的数据库选用不同的日期类型
·例如:Oracle的Date类型,只需要年月日,选择使用java.sql.Date类型
·MS Sqlserver数据库的DateTime类型,需要年月日时分秒,选择java.sql.Timestamp类型
针对不同的数据库选用不同的日期类型
·Oracle的Date类型,只需要年月日,选择使用java.sql.Date类型
·MS Sqlserver数据库的DateTime类型,需要年月日时分秒,选择java.sql.Timestamp类型
String日期格式转换成Date日期格式


1 //java.util.Date时间格式的转换 2 SimpleDateFormat f_utilDate=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 3 String str="2011-5-31 14:40:50"; 4 try { 5 java.util.Date utilDate=f_utilDate.parse(str); 6 System.out.println(f_utilDate.format(utilDate)); 7 } catch (ParseException e) { 8 // TODO Auto-generated catch block 9 e.printStackTrace(); 10 } 11 12 //java.sql.Date时间格式的转换 13 SimpleDateFormat f_sqlDate=new SimpleDateFormat("yyyy-MM-dd"); 14 java.sql.Date sqlDate = java.sql.Date.valueOf("2010-08-20"); 15 System.out.println(f_sqlDate.format(sqlDate)); 16 //java.sql.Time sqltime时间格式的转换 17 SimpleDateFormat f_sqlTime=new SimpleDateFormat("hh:mm:ss"); 18 java.sql.Time sqltime = java.sql.Time.valueOf("13:44:53"); 19 System.out.println(f_sqlTime.format(sqltime)); 20 //java.sql.Timestamp时间格式的转换 21 SimpleDateFormat f_timestamp=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS"); 22 java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2010-08-20 14:06:27.186"); 23 System.out.println(f_timestamp.format(timestamp)); 24 25 //java.util.Date 转换成 java.sql.Date 格式 26 try{ 27 SimpleDateFormat DateFormate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 28 java.util.Date date1 = DateFormate.parse("2011-5-31 14:40:50"); 29 java.sql.Date sqlDate = new java.sql.Date(date1.getTime()); 30 System.out.println(DateFormate.format(sqlDate)); 31 }catch (Exception ex) { 32 System.out.println(ex.getMessage()); 33 } 34 35 //java.sql.Date 转换成 java.util.Date 格式 36 java.sql.Date sqlDate1=java.sql.Date.valueOf("2005-12-12"); 37 java.util.Date utilDate1=new java.util.Date(sqlDate1.getTime()); 38 System.out.println("java.sql.Date 转换成 java.util.Date 格式:"+f.format(utilDate1)); 39 40 //java.util.Date转换java.sql.Timestamp 41 new java.sql.Timestamp(new java.util.Date().getTime());//此处IDE报错 42 43 //java.util.Date转换java.sql.Time 44 new java.sql.Time(new java.util.Date().getTime()); 45 46 Timestamp timestamp = new Timestamp(System.currentTimeMillis());
我们可以使用DateFormat处理字符串来定义时间日期的格式
注:String都是先转换为java.util.Date,然后再转换成所需的格式


1 try{ 2 String dateString = "2010-08-20 12:00:00.125"; 3 DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.SSS",Locale.ENGLISH);//设定格式 4 dateFormat.setLenient(false); 5 java.util.Date utilDate = dateFormat.parse(dateString);//util类型 6 java.sql.Timestamp dateTime = new java.sql.Timestamp(utilDate.getTime());//Timestamp类型,timeDate.getTime()返回一个long型 7 System.out.println(dateTime); 8 }catch(Exception ex){ 9 ex.printStackTrace(); 10 }
3.开发中建议使用这种日期转换类减少代码量
3.3自定义日期转换器
(1)内部自定义


1 @Test 2 3 public void test4() throws Exception { 4 5 // 模拟表单数据 6 7 String name = "jack"; 8 9 String birth ="1995-12-24"; 10 11 // 对象 12 13 Person2 person2 = new Person2(); 14 15 // 注册日期类型转换器:1, 自定义的方式 16 17 ConvertUtils.register(new Converter() { 18 19 // 转换的内部实现方法,需要重写 20 21 public Object convert(Class type, Object value) { 22 23 // 判断 24 25 if (type != Date.class) { 26 27 return null; 28 29 } 30 31 if (value == null || "".equals(value.toString().trim())) { 32 33 return null; 34 35 } 36 37 try { 38 39 // 字符串转换为日期 40 41 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 42 43 return sdf.parse(value.toString()); 44 45 } catch (ParseException e) { 46 47 throw new RuntimeException(e); 48 49 } 50 51 } 52 53 },java.util.Date.class); 54 55 // 把表单提交的数据,封装到对象中 56 57 BeanUtils.copyProperty(person2, "name", name); 58 59 BeanUtils.copyProperty(person2, "birthday",birth); 60 61 //------ 测试------ 62 63 System.out.println(person2.getName()); 64 65 System.out.println(person2.getBirthday()); 66 67 }
(2)设置日期格式


1 @Test 2 3 public void test5() throws Exception { 4 5 String name = "lucy"; 6 7 String birth ="1995-11-24"; 8 9 // 对象 10 11 Person2 person2 = new Person2(); 12 13 //处理时间格式 14 15 DateConverter dateConverter = new DateConverter(); 16 17 //设置日期格式 18 19 dateConverter.setPatterns(new String[]{"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"}); 20 21 //注册格式 22 23 ConvertUtils.register(dateConverter, Date.class); 24 25 // 把表单提交的数据,封装到对象中 26 27 BeanUtils.copyProperty(person2, "name", name); 28 29 BeanUtils.copyProperty(person2, "birthday",birth); 30 31 //------ 测试------ 32 33 System.out.println(person2.getName()); 34 35 System.out.println(person2.getBirthday()); 36 37 }
3.4日期类型总结
1.工具类注册日期


1 ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.sql.Date.class); 2 3 ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.util.Date.class); 4 5 ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlTimestampConverter(null), java.sql.Timestamp.class);
2.自定义日期转换器(内部)
3.自定义日期格式
https://blog.youkuaiyun.com/shuaicihai/article/details/54743546
四、 BeanUtils的应用
https://blog.youkuaiyun.com/megustas_jjc/article/details/53525026