JavaBean和BeanUtils
前面写过一篇blog来简单的介绍了JavaBean,但不全面,补充点内容
咱们先写一个JavaBean文件
public class Person {
private String name;
private int age;
public setName(String name) {
this.name = name;
}
public getName() {
return name;
}
public setAge(int age) {
this.age = age;
}
public getAge() {
return age;
}
}
设置JavaBean有两种方式
方式一:
如果我们并不知道JavaBean中有些什么属性,我们可以得到JavaBean中所有的属性描述,先调用
Introspector类中的getBeanInfo方法来获得BeanInfo的对象,然后由此对象调用getPropertyDescriptor方法
来获得JavaBean中所有属性的描述的一个数组,这样咱们遍历这个数组,稍作判断,就可以得到咱们需要设置的那个属性
我们来写一个单元测试
@Test
public void invoke1() {
//首先得到Person类的一个对象
Person person = Person.class.newInstance();
//得到BeanInfo对象
BeanInfo beaninfo = Introspector.getBeanInfo(Person.class); //得到谁的beaninfo?当然是Person的
//获得JavaBean中所有属性的描述
PropertyDescriptor[] porpertydescriptors = beaninfo.getProperDescriptor();
//遍历
for(PropertyDescriptor pd : propertydescriptors) {
System.out.println(descriptor.getName()); //打印出所有的属性
//这里是需要判断的,咱们已经打印出所有属性的名字,然后想修改哪个属性在来判断就很方便了
//如果属性的名字和name一样
if(pd.getName().equals("name")) {
//找到我们需要的属性,然后通过反射获取该属性的get和set方法
Method setMethod = pd.getWriteMethod();//获得该属性的set方法
Method getMethod = pd.getReadMethod(); //获得该属性的get方法
//然后咱们调用获得的set方法来设置属性的value
setMethod.invoke(perosn,"温家宝");
//设置好后咱们来调用属性的get方法来看看是否设置成功
System.out.println(getMethod.invoke(person));//属性的get方法一都没有参数,所以是null,也可以不写
break;
}
}
}
方式二:
如果我们非常清楚的知道自己需要设置JavaBean中的某个属性(比如age),那咱们可以通过属性描述器(Descriptor)来直接获得
此属性的描述然后同样得到属性的get和set方法,在通过反射来调用set和get,以此来达到设置和获取属性的值的目的
写个测试单元
@Test
public void invoke2() {
//首先得到Person类的一个对象
Person person = Person.class.newInstance();
//然后得到咱们需要设置的某个属性(比如age)的属性描述器
//参数分别为需要设置哪个类的哪个属性
PropertyDescriptor pd = new PropertyDescriptor("age",Person.class);
//得到该属性的描述器后,咱们就可以通过反射来得到该属性的get和set方法了
Method setMethod = pd.getWriteMethod();//获得该属性的set方法
Method getMethod = pd.getReadMethod(); //获得该属性的get方法
setMethod.invoke(perosn,56);
System.out.println(getMethod.invoke(person));
}
以上就是设置JavaBean属性的两种方式
BeranUtils
Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,
因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写
Beanutils工具包的常用类:
BeanUtils
PropertyUtils
ConvertUtils.regsiter(Converter convert, Class clazz)
自定义转换器
使用BeanUtils首先必须导入第三方jar包
之所以很多程序员都是用这套API,我想肯定是比sun公司提供的API要好用一些,的确也是,下面就介绍下BeanUtils的一些用法
JavaBean文件就用上面写的Person类,写个单元测试
@Test
public void invoke3() {
//先创建出Person对象
Person person = new Person();
//设置name属性的值
//参数如下:为哪个对象,哪个属性名,赋什么属性值
BeanUtils.copyProperty(person, "name", "胡锦涛");
//打印一下,看name的属性值是否设置成功
System.out.println(person.getName());
}
在以后学习框架中也会用到BeanUtils来设置类的一些属性,通常会用到另外一些方法
我们可以想象一下,一个类的属性,有属性名和属性值,刚好存在一个映射关系,那么我们
为什么不将这些信息存放到一个Map集合中呢?
@Test
//此单元是用Map集合的方式给属性赋值
public void invoke4() {
//先创建出Person对象
Person person = new Person();
//创建Map集合
Map<String, String> map = new HashMap<String, String>();
//向集合中添加元素,这里添加的就是属性名和属性值
map.put("name", "李嘉诚");
map.put("age", "65");
//调用populate方法来设置value,参数分别是为哪个对象设置value,存放键值的集合
BeanUtils.populate(person, map);
//这样就将属性值都设置好了,打印一下看是否成功设置
System.out.println(person.getAge());
System.out.println(person.getName());
//上面的代码其实有个小问题,age属性其实是int类型,但Map集合中存放的都是String类型的
//实际上运行没有错误,但我也不知道存在一些什么隐患,以后遇到在补充吧
}
下面在介绍几种常见的用法
1.比方说我们new出了2个Person类的对象,我们需要将person1的属性值赋给person2,注意这里是同一个类new的对象,所以
属性描述都是一样的,下面咱们就来实现这个效果
@Test
public void invoke5() {
Person person1 = new Person();
Person person2 = new Person();
//咱们先设置person1的属性
person1.setName("邓小平");
person1.setAge(98);
//然后将person1的属性赋给person2
BeanUtils.copyProperties(person2, person1);
//打印出person2中的属性
System.out.println(person2.getAge());
System.out.println(person2.getName());
}
2.上面咱们实现了同一个类中的一个对象的属性值赋给另外一个对象,那如果不是同一个类呢?
如果不是同一个类,如果想实现属性的赋值,那么必须满足这两个对象必须要有相同的属性,即必须有交集才行,
那样才能够赋值,试想一下,如果连一个相同的属性都没有,如何赋值呢?
咱们在写一个JavaBean,在这个类中我就只定义一个name属性,咱们通过Person类的对象的name属性为Man类中的name属性赋值
public class Man {
private String name;
public setName(String name) {
this.name = name;
}
public getName() {
return name;
}
}
@Test
public void invoke6() {
//分别new出这两个类的对象
Person person = new Person();
Man man = new Man();
//咱们先设置person对象的name属性值,然后赋给man对象的name属性
person.setName();
//赋值给man对象
BeanUtils.copyProperties(man, person);
System.out.println(man.getName());
}
上面BeanUtils的一些基本用法都介绍完了,下面就是一个比较重要的一个内容了,即类型转换器,我们可以把一个数据转换成
我们需要的数据类型,在strut1框架中也会用到类型转换器,其实就是BeanUtils中的类型转换器
@Test
//此单元是测试自己定义的类型转换器
/*
* 自定义类型转换器需要用到ConvertUtils类中的register方法ConvertUtils.register(Converter converter, clazz)
* 分析下参数,先看第2个参数是个class对象,那就应该是咱们需要转换的类型,如果想转换成Date类型,那就是Date.class
* 第1个参数是一个Converter类型的变量,那咱们就必须去看看API是如何定义的,一查发现Converter是一个接口,那么咱们凭
* 经验就可以知道这个接口中重写的方法就是咱们自定义的类型转换器了
*/
public void myConvertTest() {
ConvertUtils.register(new Converter() {
/*
* 先看convert方法,咱们需要把"2010-01-15"转换成Date类型
* 调用register方法,在里面咱们自定义类型转换器,看下面的方法,其中传入2个参数
*/
@Override
public Object convert(Class clazz, Object value) {
//这里就需要判断一下,看传入的参数是否为Date类型
if(clazz == Date.class){
//自定义格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
return dateFormat.parse((String)value);
} catch (ParseException e) {
throw new RuntimeException("输入的格式非法!!!");
}
}
return null;
}
}, Date.class);
Date date = (Date) ConvertUtils.convert("2010-01-15", Date.class);
System.out.println(date);
}