JSP基礎--javaBean
- 2019 年 10 月 10 日
- 筆記
JavaBean
1 JavaBean概述
1.1 什麼是JavaBean
JavaBean是一種規範,也就是對類的要求。它要求Java類的成員變數提供getter/setter方法,這樣的成員變數被稱之為JavaBean屬性。
JavaBean還要求類必須提供僅有的無參構造器,例如:public User() {…}
User.java
package cn.itcast.domain; public class User { private String username; private String 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; } } |
|---|
1.2 JavaBean屬性
JavaBean屬性是具有getter/setter方法的成員變數。
l 也可以只提供getter方法,這樣的屬性叫只讀屬性;
l 也可以只提供setter方法,這樣的屬性叫只寫屬性;
l 如果屬性類型為boolean類型,那麼讀方法的格式可以是get或is。例如名為abc的boolean類型的屬性,它的讀方法可以是getAbc(),也可以是isAbc();
JavaBean屬性名要求:前兩個字母要麼都大寫,要麼都小寫:
public class User { private String iD;[崔1] private String ID; private String qQ;[崔2] private String QQ; … } |
|---|
JavaBean可能存在屬性,但不存在這個成員變數,例如:
public class User { public String getUsername() { return "zhangSan"; } } |
|---|
上例中User類有一個名為username的只讀屬性!但User類並沒有username這個成員變數!
還可以並變態一點:
public class User { private String hello; public String getUsername() { return hello; } public void setUsername(String username) { this.hello = username; } } |
|---|
上例中User類中有一個名為username的屬性,它是可讀可寫的屬性!而Use類的成員變數名為hello!也就是說JavaBean的屬性名取決與方法名稱,而不是成員變數的名稱。但通常沒有人做這麼變態的事情。
[崔1]錯誤的JavaBean屬性
[崔2]錯誤的JavaBean屬性
JavaBean javaBean的規範: 1. 必須要有一個默認構造器 2. 提供get/set方法,如果只有get方法,那麼這個屬性是只讀屬性! 3. 屬性:有get/set方法的成員,還可以沒有成員,只有get/set方法。屬性名稱由get/set方法來決定!而不是成員名稱! 4. 方法名稱滿足一定的規範,那麼它就是屬性!boolean類型的屬性,它的讀方法可以是is開頭,也可以是get開頭!
2 內省(了解)
內省的目標是得到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"); |
|---|
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
我們這裡不想去對JavaBean規範做過多的介紹,所以也就不在多介紹BeanInfo的「出身」了。你只需要知道如何得到它,以及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屬性:
l String getName():獲取JavaBean屬性名稱;
l Method getReadMethod:獲取屬性的讀方法;
l 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"); BeanInfo beanInfo = Introspector.getBeanInfo(User.class);[崔1] PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();[崔2] User user = new User();[崔3] for(PropertyDescriptor pd : pds)[崔4] { String name = pd.getName();[崔5] String value = map.get(name);[崔6] if(value != null)[崔7] { Method writeMethod = pd.getWriteMethod();[崔8] writeMethod.invoke(user, value);[崔9] } } System.out.println(user); } |
|---|
3 commons-beanutils
提到內省,不能不提commons-beanutils這個工具。它底層使用了內省,對內省進行了大量的簡化!
使用beanutils需要的jar包:
l commons-beanutils.jar;
l commons-logging.jar;
3.1 設置JavaBean屬性
User user = new User(); BeanUtils.setProperty(user, "username", "admin");[崔10] BeanUtils.setProperty(user, "password", "admin123");[崔11] System.out.println(user); |
|---|
3.2 獲取JavaBean屬性
User user = new User("admin", "admin123"); String username = BeanUtils.getProperty(user, "username");[崔12] String password = BeanUtils.getProperty(user, "password");[崔13] 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);[崔14] System.out.println(user); |
|---|
4 JSP與JavaBean相關的動作標籤
在JSP中與JavaBean相關的標籤有:
l <jsp:useBean>:創建JavaBean對象;
l <jsp:setProperty>:設置JavaBean屬性;
l <jsp:getProperty>:獲取JavaBean屬性;
我們需要先創建一個JavaBean類:
User.java
package cn.itcast.domain; 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 + "]"; } } |
|---|
4.1 <jsp:useBean>
<jsp:useBean>標籤的作用是創建JavaBean對象:
l 在當前JSP頁面創建JavaBean對象;
l 把創建的JavaBean對象保存到域對象中;
<jsp:useBean id="user1" class="cn.itcast.domain.User" /> |
|---|
上面程式碼表示在當前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/> |
|---|
[崔1]獲取User類型的BeanInfo實例
[崔2]獲取User類型的所有JavaBean屬性的屬性描述符對象
[崔3]創建User實例
[崔4]循環遍歷每個屬性描述符對象
[崔5]獲取JavaBean屬性名
[崔6]獲取Map中對應屬性的值
[崔7]如果在Map中存在這個屬性的值
[崔8]獲取該屬性的寫方法
[崔9]把Map中的值寫入到user對象的對應屬性中
[崔10]設置user對象的username屬性為admin
[崔11]設置user對象的password屬性為admin123
[崔12]獲取user對象的username屬性值
[崔13]獲取user對象的password屬性值
[崔14]把map中的數據封裝到user對象中,要求user的屬性名要與map的key一致。
內省: 內省類 --> Bean資訊 --> 屬性描述符 --> 屬性的get/set對應的Method! --- > 可以反射了! ----------------------- commons-beanutils,它是依賴內省完成! * 導包: > commons-beanutils.jar > commons-logging.jar BeanUtils.getProperty(Object bean, String propertyName) BeanUtils.setProperty(Object bean, String propertyName, String propertyValue) BeanUtils.populate(Map map, Object bean) CommontUtils.toBean(Map map, Class class) ----------------------- jsp中與javaBean相關的標籤! * <jsp:useBean> --> 創建或查詢bean * <jsp:useBean id="user1" class="cn.itcast.domain.User" scope="session"/> 在session域中查找名為user1的bean,如果不存在,創建之 * <jsp:useBean id="user1" class="cn.itcast.domain.User" scope="session"/> * <jsp:setProperty> * <jsp:setProperty property="username" name="user1" value="admin"/> 設置名為user1的這個javabean的username屬性值為admin * <jsp:getProperty> * <jsp:getProperty property="username" name="user1"/> 獲取名為user1的javabean的名為username屬性值