Apache commons 一系列的開源工具室很是值得學習的實現。
一 JavaBean定義
JavaBean是一種可重複使用、且跨平臺的軟件組件。JavaBean可分爲兩種:一種是有用戶界面(UI,User Interface)的 JavaBean;還有一種是沒有用戶界面,主要負責處理事務(如數據運算,操縱數據庫)的JavaBean。JSP一般訪問的是後一種JavaBean。 java
二 JavaBean特色
一個標準的JavaBean有如下幾個特性: 數據庫
- JavaBean是一個公共的(public)類
- JavaBean有一個不帶參數的構造方法
- JavaBean經過setXXX方法設置屬性,經過 getXXX方法獲取屬性
三 JSP中訪問JavaBean
3.1 導入JavaBean類
- 經過<%@ page import> 指令導入JavaBean類,例如: <%@ page import="mypack.CounterBean" %>
3.2 聲明JavaBean的對象
- 聲明JavaBean 對象使用<jsp:useBean>標籤,例如: <jsp:useBean id="myBean" class="mypack.CounterBean" scope="session" />
-
<jsp:useBean>標籤中各屬性含義:
- id 是在所定義的範圍中確認Bean的變量,使之能在後面的程序中使用此變量名來分辨不一樣的Bean,這個變量名對大小寫敏感,必須符合所使用的腳本語言的規定。
- class 指定bean由哪一個類建立。
- scope 指定bean的存活範圍。
3.3 訪問JavaBean屬性
-
若是要給JavaBean 的某個屬性賦值,能夠用 <jsp:setProperty>標籤,例如:<jsp:setProperty name="myBean" property="count" value="0" /> 將id爲myBean(name的值)的Bean的count的值設置爲"0"(value的值)。
-
若是要將JavaBean的某個屬性輸出到網頁上,能夠用 <jsp:getProperty>標籤,例如:<jsp:getProperty name="myBean" property="count" /> 得到id爲myBean(name的值)的bean的count屬性的值。
3.4 bean的存活範圍:
scope屬性決定了JavaBean對象存在的範圍 。 express
scope的可選值包括: 數組
-
page(默認值):客戶每次請求訪問JSP頁面時,都會建立一個JavaBean對象。JavaBean對象的有效範圍是客戶請求訪問的當前JSP網頁。 JavaBean對象在如下兩種狀況下都會結束生命期:
- 客戶請求訪問的當前JSP網頁經過<forward> 標記將請求轉發到另外一個文件
- 客戶請求訪問的當前JSP頁面執行完畢並向客戶端發回響應。
-
request:客戶每次請求訪問JSP頁面時,都會建立新的 JavaBean對象。
-
JavaBean對象的有效範圍爲:
- 客戶請求訪問的當前JSP網頁
- 和當前JSP網頁共享同一個客戶請求的網頁,即當前JSP網頁中<%@ include>指令以及<forward>標記包含的其餘JSP文件
- 當全部共享同一個客戶請求的JSP頁面執行完畢並向客戶端發回響應時,JavaBean對象結束生命週期
- JavaBean對象做爲屬性保存在HttpRequest 對象中,屬性名爲JavaBean的id,屬性值爲JavaBean對象,所以也能夠經過HttpRequest.getAttribute()方法取得JavaBean對象,例如:CounterBean obj=(CounterBean)request.getAttribute("myBean");
-
session:JavaBean對象被建立後,它存在於整個Session的生存週期內,同一個Session中的JSP文件共享這個JavaBean對象。
- JavaBean對象做爲屬性保存在HttpSession 對象中,屬性名爲JavaBean的id,屬性值爲 JavaBean對象。除了能夠經過JavaBean的 id直接引用JavaBean對象外,也能夠經過 HttpSession.getAttribute() 方法取得 JavaBean對象,例如:CounterBean obj=(CounterBean)session.getAttribute("myBean");
-
application:JavaBean對象被建立後,它存在於整個 Web應用的生命週期內,Web應用中的全部 JSP文件都能共享同一個JavaBean對象。
- JavaBean對象做爲屬性保存在application對 象中,屬性名爲JavaBean的id,屬性值爲JavaBean對象,除了能夠經過JavaBean的id直接引用JavaBean對象外,也能夠經過application.getAttribute()方法取得JavaBean對象,例如:CounterBean obj=(CounterBean)application.getAttribute("myBean");
四 Javabean的內省操做
在java的反射中,全部的類被抽象出一個類,即Class類,這樣咱們就能夠在程序運行的過程當中經過配置文件,動態的加載類。可是在用反射的時候有些前提,就是:當咱們調用有參的constructor的時候必須先知道構造函數傳入的參數是什麼類型;調用Method的時候必須先知道成員函數傳入的參數是什麼類型;調用field的時候必須先知道成員變量的類型。可是在某些狀況下,一個類中的成員屬性的名字對外是不可見的,這時候咱們只能夠得出他的成員類型的數組field[],在不知道確切變量名的狀況下不能夠定位到確切的變量上。而他提供了對這個屬性公開的讀(get)、寫(set)方法, 雖然方法名和方法操做的對象有時候有很大的關係,可是咱們不能保證這個關係必定成立。並且這種只提供get、set方法,不提供變量名的狀況還很常見,所以java就將這種抽象爲javabean類,對javabean類的操做,經過get、set函數後面的名字就"擬"得出變量的名字。經過這個名字,咱們能夠確切的求出某個變量的值。而對javabean的操做是經過內省(introspector)來完成的。 session
4.1 對Javabean的簡單的內省操做
問題 已知一個ReflectionPoint對象中有個私有變量的名字叫作'x'問採用反射如何獲得它的值呢? app
-
/**
-
* 實體內部類
-
*/
-
class ReflectionPoint{
-
private int x;
-
pirvate int y;
-
public ReflectionPoint(int x,int y){
-
this.x = x;
-
this.y = y;
-
}
-
public void setX(int x){
-
this.x = x;
-
}
-
public int getX(){
-
return x;
-
}
-
public void setY(int y){
-
this.y = y;
-
}
-
public int getY(){
-
return y;
-
}
-
/**
-
* main方法
-
*/
-
public static void main(String[] args) throws Exception{
-
ReflectionPoint rp = new ReflectionPoint(3,5);
-
String propertyName = "x";
-
//利用反射,那咱們會分析一步一步獲得其屬性的get方法: x -->X --->getX --->MethodGetX--操做
-
//可想而知這樣有點太麻煩了。咱們並沒有法肯定每一個屬性名稱命名規範,因此致使咱們獲取方法時會有必定困難
-
//不過JavaBean類中給咱們提供了一些簡便的類PropertyDescriptor
-
//專門用於操做JavaBean對象的類PropertyDescriptor
-
PropertyDescriptor pd = new PropertyDescriptor(propertyName, rp.getClass());//建立一個針對該JavaBean類和屬性名的屬性描述對象
-
//getReadMethod()就至關於獲得get方法,而getWriteMethod()就至關因而屬性的set方法了。
-
Method MethodGetX = pd.getReadMethod();
-
//獲得某個對象上的某個屬性值
-
Object retValue = MethodGetX.invoke(rp);
-
//System.out.println(retValue);
-
-
Method MethodSetY = pd.getWriteMethod();
-
//設置某個對象上的某個屬性值是7
-
MethodSetY.invoke(rp, 7);
-
System.out.println(rp.getX());
-
-
}
4.2 對Javabean的複雜內省操做
固然也可以使用Introspector類來完成這個功能,經過調用Introspector類的靜態方法getBeanInfo獲得一個BeanInfo類的對象,這個類能夠把一個普通的類當成Javabean來看待 ,經過這個對象來獲得全部屬性的獲得全部屬性的描述的集合,而後採用遍歷的方式逐一進行查找該屬性,經過反射獲得該方法,具體代碼以下: jsp
Java代碼
函數
-
BeanInfo bi = Introspector.getBeanInfo(rp.getClass());
-
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
-
Object retValue = null;
-
-
for(PropertyDescriptor pd2 : pds) {
-
if(pd2.getName().equals(propertyName)) {
-
Method MethodGetX = pd2.getReadMethod();
-
retValue = MethodGetX.invoke(rp);
-
break;
-
}
-
-
}
使用BeanUtils工具包操做Javabean對象: 工具
Java代碼
學習
-
/**
-
* 利用BeanUtils工具類來調用屬性
-
*/
-
System.out.println(BeanUtils.getProperty(stu, propertyName));
-
System.out.println(BeanUtils.getProperty(stu, propertyName).getClass().getName());
-
BeanUtils.setProperty(stu, "name", "前三");
-
System.out.println(BeanUtils.getProperty(stu, propertyName));
-
-
//設置一個對象的屬性
-
BeanUtils.setProperty(stu,"birthday.time","111");
-
System.out.println(BeanUtils.getProperty(stu, "birthday.time"));
-
System.out.println(retVal);
-
-
/*//Jdk1.7新特性,設置map對象
-
Map map = {name:"zhansan",age:12};
-
BeanUtils.setProperty(map, name, "zhans");*/
-
-
//另外一種設置屬性的方式
-
-
PropertyUtils.setProperty(stu, propertyAge, 5);
-
-
System.out.println(PropertyUtils.getProperty(stu, propertyAge).getClass().getName());