JavaBean特性
- JavaBean必须要有一个默认构造器(无参的)
- 提供get/set方法,如果只有get方法,是只读属性
- 属性:有get/set方法,可以没有成员,只有get/set方法。属性名由get/set方法决定,而不是成员名称。
- 方法名称满足一定的规范,它就是属性。Boolean类型的属性,它的读方法可以是is开头,也可以是get开头。(JavaBean属性名要求:前两个字母要么都大写,要么都小写)
内省(内省底层依赖反射)
内省的目标是得到JavaBean属性的读、写方法的反射对象,通过反射对JavaBean属性进行操作的一组API。
实例作用:对一个user对象,它有2个JavaBean属性,username,password(这是两个私有属性)。现在需要将map数据封装到一个user对象中。可以通过反射,但是不安全。通过get/set方法就可以轻松做到。
内省获取BeanInfo
通过Java.beans.Introspector的getBeanInfo()方法来获取java.beans.BeanInfo实例
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
得到所有属性描述符(PropertyDesciptor)
通过BeanInfo 可以得到这个类的所有javaBean属性的PropertyDescrptor对象。再通过PropertyDescrptor对象得到属性get/set方法的Method对象。
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
每个PropertyDescriptor对象对应一个JavaBean属性:
- String getName():获取JavaBean属性名称;
- Method getReadMethod:获取属性的读方法;
- Method getWriteMethod:获取属性的写方法。
使用BeanInfo 实现将Map数据封装到User对象中
User类
public class User {
private String username;
private String password;
@Override
public String toString() {
return "["+"username:"+username+";"+"password:"+password+"]";
}
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 User(){
super();
}
//有参构造函数
public User(String username,String name){
super();
this.username=username;
this.password=name;
}
}
使用BeanInfo操作类
@Test
public void fun1() throws Exception{
Map<String,String> umap=new HashMap<>();
umap.put("username","张三");
umap.put("password", "123");
User user=new User();
BeanInfo info=Introspector.getBeanInfo(user.getClass());
PropertyDescriptor[] propertyDescriptors=info.getPropertyDescriptors();
for(PropertyDescriptor item:propertyDescriptors){
String name=item.getName();
String value=umap.get(name);
if(value!=null){
Method method=item.getWriteMethod();
method.invoke(user, value);
}
}
System.out.println(user.toString());
}
commons-beanutils工具使用
底层使用了内省,对内省进行了大量的简化。
使用beanutils需要两个jar包
- commons-beanutils.jar;
- commons-logging.jar;
设置javaBean属性
@Test
public void fun4() throws Exception{
User user=new User();
BeanUtils.setProperty(user, "username", "陈六");
BeanUtils.setProperty(user, "password", "123456");
System.out.println(user);
}
获取javaBean属性
@Test
public void fun3() throws Exception{
User user=new User("王五","12345");
String username=BeanUtils.getProperty(user, "username");
System.out.println(username);
}
将Map数据封装到JavaBean对象中
@Test
public void fun2() throws Exception{
User user=new User();
Map<String,String> umap=new HashMap<>();
umap.put("username","李四");
umap.put("password","1234");
BeanUtils.populate(user, umap);
System.out.println(user);
}
JSP与JavaBean相关的动作标签
- <jsp:useBean>:创建JavaBean对象
- <jsp:setProperty>:设置JavaBean属性值
- <jsp:getProperty>:获取JavaBean属性
<jsp:useBean>:创建JavaBean对象
<jsp:useBean id="user1" class="cn.sicau.User" />
查看page域中是否存在user1这个域属性,如果存在,那么直接获取。
如果不存在,那么创建之!
等同与:
User user1 = pageContext.getAttribute("user1");
if(user1 == null) {
user1 = new User();//创建user1对象
pageContext.setAttribute("user1", user1);//保存到page域
}
-----------------
上面是操作page域,可以通过scope属性来指定操作的域
<jsp:useBean id="user1" class="cn.sicau.User" scope="page"/>
<jsp:useBean id="user2" class="cn.sicau.User" scope="request"/>
<jsp:useBean id="user3" class="cn.sicau.User" scope="session"/>
<jsp:useBean id="user4" class="cn.sicau.User" scope="applicatioin"/>
<jsp:setProperty>:设置属性值
<jsp:setProperty property="username" name="user1" value="admin"/>
- name:指定名为user1的JavaBean
- property:指定要设置的属性名称
- value:指定要设置的属性值
等同与
User user1 = (User)pageContext.getAttribute("user1");
user1.setUsername("admin");
------------------
<jsp:getProperty>:获取属性值
<jsp:getProperty property="username" name="user1"/>
输出user1这个javaBean的username属性值
等同与
User user1 = (User)pageContext.getAttribute("user1");
out.print(user1.getUsername());