jsp useBean元素使用全解

【前言】擡頭仰望活在網絡上的各位牛人們,是他們讓我學習到很多新的東西,也讓我明白了學無止境

 

【原文】

http://turingbook.group.javaeye.com/group/blog/577256

http://www.wang48.com/jishubaodianview/?jsd_id=201

 

jsp:useBean動作用來裝載一個將在JSP頁面中使用的JavaBean。這個功能非常有用,因爲它使得我們既可以發揮Java組件重用的優勢,同時也避免了損失JSP區別於Servlet的方便性。

 

一. JSP動作元素useBean語法:

    <jsp:useBean
        id="beanInstanceName"
        scope="page | request | session | application"
        {
            class="package.class" |
            type="package.class" |
            class="package.class" type="package.class" |
            beanName="{package.class | <%= expression %>}"
type="package.class"
        }
        {
            /> |
            > other elements </jsp:useBean>
        }

二. JSP動作元素useBean使用示例:

<jsp:useBean id="cart" scope="session" class="session.Carts" />
<jsp:setProperty name="cart" property="*" />

<jsp:useBean id="checking" scope="session" class="bank.Checking" >
<jsp:setProperty name="checking" property="balance" value="0.0" />
</jsp:useBean>

這些代碼的含義是:“創建一個由class屬性指定的類的實例,然後把它綁定到其名字由id屬性給出的變量上,當該javabean不存在時,就執行藍色的body部分;當該javabean已經創建時,就不執行藍色的body部分”。此時,jsp:useBean動作只有在不存在同樣id和scope的Bean時才創建新的對象實例,同時,獲得現有Bean的引用就變得很有必要。

 

獲得Bean實例之後,要修改Bean的屬性既可以通過jsp:setProperty動作進行,也可以在Scriptlet中利用id屬性所命名的對象變量,通過調用該對象的方法顯式地修改其屬性。這使我們想起,當我們說“某個Bean有一個類型爲X的屬性foo”時,就意味着“這個類有一個返回值類型爲X的getFoo方法,還有一個setFoo方法以X類型的值爲參數”。



三. JSP動作元素useBean執行步驟:

    <jsp:useBean>元素用來定位或初始化一個JavaBeans組件。(註解,這個標籤有兩個作用)。<jsp:useBean>首先會嘗試定位Bean實例,如果其不存在,則會依據class名稱(class屬性指定)或序列化模板(beanName屬性指定)進行實例化。

    進行定位或初始化Bean對象時,<jsp:useBean>按照以下步驟執行。

步驟1: 嘗試在scope屬性指定的作用域使用你指定的名稱(id屬性值)定位Bean對象;(註解,由scope和id共同決定)
步驟2: 使用你指定的名稱(id屬性值)定義一個引用類型變量;
步驟3: 假如找到Bean對象,將其引用給步驟2定義的變量。假如你指定類型(type屬性),賦予該Bean對象該類型;
步驟4: 假如沒找到,則實例化一個新的Bean對象,並將其引用給步驟2定義的變量。假如該類名(由beanName屬性指定的類名)代表的是一個序列化模板(serialized template),該Bean對象由java.beans.Beans.instantiate初始化;
步驟5: 假如<jsp:useBean>此次是實例化Bean對象而不是定位Bean對象,且它有體標記(body tags)或元素(位於<jsp:useBean>和</jsp:useBean>之間的內容,則執行該體標記。

<jsp:useBean>和</jsp:useBean>之間經常包含<jsp:setProperty>,用來設置該Bean的屬性值。正如步驟5所描述的,該元素僅在<jsp:useBean>實例化Bean對象時處理。假如Bean對象早已存在,<jsp:useBean>是定位到它,則體標記毫無用處。

我們可以使用<jsp:useBean>元素來定位或實例化一個JavaBean對象,但不能是
EJB。對於EJB,我們可以通過創建自定義標記來直接調用彧採用其它方式。

四. <jsp:useBean>元素各屬性解析:

1. id="beanInstanceName"
       
        一個用來標識你指定作用域的變量。可以在JSP文件的表達式或腳本小應
        用程序中使用該變量名稱。
       
        該名稱大小寫敏感,必須符合JSP頁面中腳本語言的命名規則。假如你使
        用的是Java語言,則該名稱遵守的是Java命名規範。假如該Bean對象已由
        其它<jsp:useBean>元素創建,則該值必須和實例化該Bean對象
        的<jsp:useBean>元素id屬性值一致,才能實現定位到該Bean對象。
       
2. scope="page | request | session | application"
       
        Bean對象存在的作用範圍,默認值爲 page. 不同作用域解釋如下:(註解,訪問範圍由小到大)
        
        
        1) page: 你可以在<jsp:useBean>元素所在JSP頁面或其靜態包含頁面使
        用該JavaBean對象,直到該頁面發送響應回客戶端或跳轉(forwards)至其
        它頁面。
               
        2) request: 你可以在處理同一個請求的任意一個頁面使用該JavaBean對
        象,直到該頁面發送響應回客戶端或產生新的請求。你可以使用request
        對象訪問該JavaBean對象,示例:
           request.getAttribute(beanInstanceName).
               
       3) session: 你可以在同一次會話的任意一個頁面使用該JavaBean對象,該
       JavaBean對象在整個會話期間一直存在。

 

       使用<jsp:useBean/>創建JavaBean對象的頁面的<%@page %>指令元

       素的session屬性值必須設置爲true;
               
       4) application: 你可以在創建該JavaBean對象的同一個應用的任意一個頁面
       使用該JavaBean對象,該JavaBean對象在整個應用期間一直存在。應用中任

       意一個頁面均可使用它。

3. class="package.class"
       
       
        從一個class實例化Bean對象,使用new關鍵字調用class的構造方法完
        成。
        該 class 必須不能是抽象必須有一個 public、無參的構造器。包名和
        類名稱大小寫敏感。
       
4. type="package.class"

        用來指定該Bean對象的數據類型,假如既沒有指定 class 或 beanBean, 沒
        有Bean對象能被實例化。包和類名稱大小寫敏感。它必須是Bean類的名字、超

        類名字、該類所實現的接口名字之一。請記住變量的名字是由id屬性指定的。

5. class="package.class" type="package.class"
       
       
        使用class屬性指定的類實例化JavaBean對象,並聲明其數據類型爲type
        屬性指定的類型;type屬性值可和class屬性值同,或爲其超類、接口。
       
        class屬性中所指定類名稱必須不能爲抽象的,必須包含有public,無參的
        構造方法。class和type屬性所指定的包名,類名均大小寫敏感。

6. beanName="{package.class | <%= expression %>}" type="package.class"

       使用java.beans.Beans.instantiate方法實例化beanName屬性指定的類或序列
       化模板對應的Bean對象,賦予JavaBean對象type屬性指定的數據類型。
       Beans.instantiate方法會檢查beanName屬性指定的名稱是類名稱還是序列化模板
       的名稱。假如該JavaBean對象已被序列化,則Beans.instantiate使用類加載器讀
       取序列化的內容,更多信息可參考JavaBeans.

       beanName屬性值要麼是一個完整類名,要麼是一個可以轉化爲完整類名的表達式。
       用來傳給Beans.instantiate方法。type屬性值可和beanName屬性值同,或爲其超
       類、接口。

       beanName和type屬性所指定的包名,類名均大小寫敏感。

五. JSP動作元素useBean使用剖析: (註解,這裏講的很有用)

對於<jsp:useBean>執行步驟的理解,我們可以通過閱讀JSP轉化成的Servlet源碼完成。以下給出二段示意代碼, 可參閱之前步驟進行深化理解:

1) 通過beanName指定要實例化的JavaBean類名:

JSP源碼 :
-----------------------------------
<jsp:useBean id="u" type="bean.User" beanName="bean.User"/>

JSP轉譯成Servlet的源碼 :
-----------------------------------
      bean.User u = null;
      synchronized (_jspx_page_context) {
        u = (bean.User) _jspx_page_context.getAttribute("u",
PageContext.PAGE_SCOPE);   //註解,這個是scope
        if (u == null){
          try {
            u = (bean.User)
java.beans.Beans.instantiate(this.getClass().getClassLoader(),
"bean.User");
          } catch (ClassNotFoundException exc) {
            throw new InstantiationException(exc.getMessage());
          } catch (Exception exc) {
            throw new ServletException("Cannot create bean of class " +
"bean.User", exc);
          }
          _jspx_page_context.setAttribute("u", u,
PageContext.PAGE_SCOPE);
        }
      }

2) 通過class指定要實例化的JavaBean類名:

JSP源碼 :
----------------------------------
<jsp:useBean id="u" type="bean.User" class="bean.User"/>

JSP轉譯成Servlet的源碼 :
------------------------------------
-------
      bean.User u = null;
      synchronized (_jspx_page_context) {
        u = (bean.User) _jspx_page_context.getAttribute("u",
PageContext.PAGE_SCOPE);
        if (u == null){
          u = new bean.User();     //註解,這個直接用new創建bean
          _jspx_page_context.setAttribute("u", u,
PageContext.PAGE_SCOPE);
        }
      }

六. 注意幾點:

1) class或beanName不能同時存在;它們用來指定實例化的類名稱或序列化模板;如果確信JavaBean對象已存在,class和beanName屬性均可無須指定, 可只須指定type屬性。
2) class可以省去type獨自存在,beanName必須和type一起使用;
3) class指定的是類名,beanName指定的是類名或序列化模板的名稱;
4) class指定的類名必須包含public、無參的構造方法;在對象已實例化時,beanName指定的名稱可以爲其接口、父類;
5) 如果JavaBean對象已存在,<jsp:useBean>只是用來定位JavaBean,則只需使用type屬性即可,class和beanName這時捨去不影響使用。
6) class或beanName指定的類名必須包括包名稱,type可以省去包名,通過<%@page import=""%>指定所屬包亦可。
7) class通過new創建JavaBean對象;beanName通過java.beans.Beans.instantiate初始化JavaBean對象。

8) jsp:useBean並非總是意味着創建一個新的Bean實例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章