JavaBean简介
一、JavaBean概述
1. 什么是JavaBean
JavaBean是一种规范,也就是对类的要求。
它要求Java类的成员变量提供getter/setter方法,这样的成员变量被称之为JavaBean属性。JavaBean还要求类必须提供仅有的无参构造器。
例如下面这个Person类:
public class Person {
private String name;
private int age;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
public Person() {
super();
}
public Person(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
}
2. JavaBean属性
JavaBean属性是具有get/set方法的成员变量。
- 也可以只提供get方法,这样的属性叫只读属性;
- 也可以只提供set方法,这样的属性叫只写属性;
- 如果属性类型为boolean类型,那么读方法的格式可以是get或is。例如名为abc的boolean类型的属性,它的读方法可以是
getAbc()
,也可以是isAbc()
。
JavaBean属性名的要求,前两个字母要么都大写,要么都小写:
private class User{
private String iD; //错误的
private String ID;
private String Qq; //错误的
private String QQ;
}
还有一种可能,JavaBean存在属性,但是不存在这个成员变量,例如:
public class User{
Public String getUsername(){
return "ZhangSan";
}
}
还可以属性名称与成员变量的名称不一样:
public class User {
private String hello;
public String getUsername() {
return hello;
}
public void setUsername(String username) {
this.hello = username;
}
}
上面这个例子中,有getUsername()
和setUsername()
方法,所以就有一个名为username的属性,但是没有这样的成员变量,这样也是可以的,而且,属性的名称为username,而不是hello。
也就是说,Javabean的属性名称取决于方法名称,而不是成员变量的名称。但是一般不这么做。
二、内省(了解)
内省的目标是得到JavaBean属性的读、写方法的反射对象,通过反射对JavaBean属性进行操作的一组API。例如User类有名为username的JavaBean属性,通过两个Method对象(一个是getUsenrmae()
,一个是setUsername()
)来操作User对象。
我们举一个例子:
现在有一个Map,内容如下:
Map<String,String> map = new HashMap<String,String>();
map.put("username", "admin");
map.put("password", "admin123");
有一个User类:
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属性。
2.1 内省获取BeanInfo
通过java.beans.Introspector的getBeanInfo()方法来获取java.beans.BeanInfo实例。
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
2.2 得到所有属性描述符(PropertyDescriptor)
通过BeanInfo可以得到这个类的所有JavaBean属性的PropertyDescriptor对象。然后就可以通过PropertyDescriptor对象得到这个属性的getter/setter方法的Method对象了。
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
每个PropertyDescriptor对象对应一个JavaBean属性:
- String getName():获取JavaBean属性名称;
- Method getReadMethod:获取属性的读方法;
- Method getWriteMethod:获取属性的写方法。
2.3 完成Map数据封装到User对象中
完整的代码:
public void fun1() throws Exception {
Map<String,String> map = new HashMap<String,String>();
map.put("username", "admin");
map.put("password", "admin123");
// 获取User类型的BeanInfo实例
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
// 获取User类型的所有JavaBean属性的属性描述符对象
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
// 创建User实例
User user = new User();
// 循环遍历每个属性描述符对象
for(PropertyDescriptor pd : pds) {
// 获取JavaBean属性名
String name = pd.getName();
// 获取Map中对应属性的值
String value = map.get(name);
// 如果在Map中存在这个属性的值
if(value != null) {
// 获取该属性的写方法
Method writeMethod = pd.getWriteMethod();
// 把Map中的值写入到user对象的对应属性中
writeMethod.invoke(user, value);
}
}
System.out.println(user);
}
三、commons-beanutils
提到内省,不能不提commons-beanutils这个工具。它底层使用了内省,对内省进行了大量的简化!
使用beanutils需要的jar包:
- commons-beanutils.jar;
- commons-logging.jar;
3.1 设置JavaBean属性
User user =new User();
BeanUtils.setProperty(user, "username", "admin");
BeanUtils.setProperty(user, "password", "admin123");
System.out.println(user);
3.2 获取JavaBean属性
User user = new User("admin", "admin123");
String username = BeanUtils.getProperty(user, "username");
String password = BeanUtils.getProperty(user, "password");
System.out.println("username=" + username + ", password=" + password);
3.3 封装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);
System.out.println(user);
四、JSP与JavaBean相关的动作标签
在JSP中与JavaBean相关的标签有:
<jsp:useBean>
:创建JavaBean对象;<jsp:setProperty>
:设置JavaBean属性;<jsp:getProperty>
:获取JavaBean属性;
4.1<jsp:useBean>
<jsp:useBean>
标签的作用是创建JavaBean对象:
- 在当前JSP页面创建JavaBean对象;
把创建的JavaBean对象保存到域对象中;
上面代码表示在当前JSP页面中创建User类型的对象,并且把它保存到page域中了。下面我们把jsp:useBean标签翻译成Java代码:
<%
cn.itcast.domain.User user1 = new cn.itcast.domain.User();
pageContext.setAttribute("user1", user1);
%>
这说明我们可以在JSP页面中完成下面的操作:
<jsp:useBean id="user1" class="cn.itcast.domain.User" />
<%=user1 %>
<%
out.println(pageContext.getAttribute("user1"));
%>
<jsp:useBean>
标签默认是把JavaBean对象保存到page域,还可以通过scope标签属性来指定保存的范围:
<jsp:useBean id="user1" class="cn.itcast.domain.User" scope="page"/>
<jsp:useBean id="user2" class="cn.itcast.domain.User" scope="request"/>
<jsp:useBean id="user3" class="cn.itcast.domain.User" scope="session"/>
<jsp:useBean id="user4" class="cn.itcast.domain.User" scope="applicatioin"/>
<jsp:useBean>
标签其实不一定会创建对象!!!其实它会先在指定范围中查找这个对象,如果对象不存在才会创建,我们需要重新对它进行翻译:
<jsp:useBean id="user4" class="cn.itcast.domain.User" scope="applicatioin"/>
<%
cn.itcast.domain.User user4 = (cn.itcast.domain.User)application.getAttribute("user4");
if(user4 == null) {
user4 = new cn.itcast.domain.User();
application.setAttribute("user4", user4);
}
%>
4.2 <jsp:setProperty>
和<jsp:getProperty>
<jsp:setProperty>
标签的作用是给JavaBean设置属性值,而<jsp:getProperty>
是用来获取属性值。在使用它们之前需要先创建JavaBean:
<jsp:useBean id="user1" class="cn.itcast.domain.User" />
<jsp:setProperty property="username" name="user1" value="admin"/>
<jsp:setProperty property="password" name="user1" value="admin123"/>
用户名:<jsp:getProperty property="username" name="user1"/><br/>
密 码:<jsp:getProperty property="password" name="user1"/><br/>
end.
还没有评论,来说两句吧...