1.JavaBean概述
在看这篇文章之前,你必须要知道什么是JavaBean JavaBean的概述
2.内省(了解)
内省是Java语言对Bean类属性、事件的一种缺省处理方法。例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。通过getName/setName来访问name属性,这就是默认的规则。Java中提供了一套API用来访问某个属性的getter/setter方法,通过这些API可以使你不需要了解这个规则,这些API存放于包java.beans中。
一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。
其中内省的类就是Introspector。
如果你还不能理解内省是什么,那么我们通过一个问题来了解内省的作用。现在我们有一个Map,内容如下:
Map<String,String> map = new HashMap<String,String>();
map.put("username", "admin");
map.put("password", "admin123");
public class User {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public User() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
现在需要把map的数据封装到一个User对象中!User类有两个JavaBean属性,一个叫username,另一个叫password。
你可能想到的是反射,通过map的key来查找User类的Field!这么做是没有问题的,但我们要知道类的成员变量是私有的,虽然也可以通过反射去访问类的私有的成员变量,但我们也要清楚反射访问私有的东西是有“危险”的,所以还是建议通过getUsername和setUsername来访问JavaBean属性。
总结:
内省是Java语言对Bean类属性、事件的一种缺省处理方法。
3.内省之获取BeanInfo
简介:
在以前可视化界面编程的时候,一般要想定义一个可以拖拽的控件,都要定义一个BeanInfo。
BeanInfo是对JavaBean的集合体描述,其中包括属性,方法等。
通过java.beans.Introspector的getBeanInfo()方法来获取java.beans.BeanInfo实例。
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
1.得到所有属性描述符(PropertyDescriptor)
- 通过BeanInfo可以得到这个类的所有JavaBean属性的PropertyDescriptor对象。然后就可以通过PropertyDescriptor对象得到这个属性的getter/setter方法的Method对象了。
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
每个PropertyDescriptor对象对应一个JavaBean属性:
- String getName():获取JavaBean属性名称;
- Method getReadMethod:获取属性的读方法;
- Method getWriteMethod:获取属性的写方法。
2.完成Map数据封装到User对象中
public void fun1() throws Exception {
Map<String,String> map = new HashMap<String,String>();
map.put("username", "admin");
map.put("password", "admin123");
BeanInfo beanInfo = Introspector.getBeanInfo(User.class); //获取User类型的BeanInfo实例
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); //获取User类型的所有JavaBean属性的属性描述符对象
User user = new User(); //创建User实例
for(PropertyDescriptor pd : pds) {//循环遍历每个属性描述符对象
String name = pd.getName(); //获取JavaBean属性名
String value = map.get(name); //获取Map中对应属性的值
if(value != null) {//如果在Map中存在这个属性的值
Method writeMethod = pd.getWriteMethod(); //获取该属性的写方法
writeMethod.invoke(user, value); //把Map中的值写入到user对象的对应属性中
}
}
System.out.println(user);
}
前面介绍了BeanInfo的基本应用。下面介绍commons-beanutils
4.commons-beanutils
提到内省,不能不提commons-beanutils这个工具。它底层使用了内省,对内省进行了大量的简化!
使用beanutils需要的jar包:
- commons-beanutils.jar;
- commons-logging.jar;
- 下载地址
设置JavaBean属性
User user = new User();
BeanUtils.setProperty(user, "username", "admin"); //设置user对象的username属性为admin
BeanUtils.setProperty(user, "password", "admin123"); //设置user对象的password属性为admin123
System.out.println(user);
获取JavaBean属性
User user = new User("admin", "admin123");
String username = BeanUtils.getProperty(user, "username"); //获取user对象的username属性值
String password = BeanUtils.getProperty(user, "password"); //获取user对象的password属性值
System.out.println("username=" + username + ", password=" + password);
封装Map数据到JavaBean对象中
Map<String,String> map = new HashMap<String,String>();
map.put("username", "admin");
map.put("password", "admin123");
User user = new User();
BeanUtils.populate(user, map); //把map中的数据封装到user对象中,要求user的属性名要与map的key一致。
System.out.println(user);
在这里就必须提一下在JavaWeb中的数据封装了。当用户提交表单上来后,可以使用request.getParramaterMap();方法获取表单Map对象,然后就可以使用commons-beanutils来进行数据的转换了。