<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kapok

    垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      455 隨筆 :: 0 文章 :: 76 評論 :: 0 Trackbacks
    http://www.uml.org.cn/j2ee/j2ee003.htm

    J2EE組件間共享對象技術
    作者:龔永生    本文選自:開放系統世界—賽迪網  2003年02月26日
    想要用好Struts應用框架,必須了解J2EE Web級JSP和Servlet技術存放共享對象的幾種方式。同時,要利用J2EE 開發Web應用程序也必須掌握組件間對象共享的機制。

    像Java程序有類級別變量、方法級別變量一樣,J2EE Web應用程序有四個對象存放共享對象。這些共享對象存放在那里,以便存放者或者其它程序代碼日后使用。這四個對象分別是頁面、請求、會話和應用程序,它們都是以數據結構鍵/值對的形式保存的。同時這四個對象形成了四個級別的共享對象存放地,即應用程序對象中的共享對象是全局性的,在整個應用程序的生命周期內有效(當然主動去掉除外),屬于所有的上網用戶;會話對象中的共享對象是在一個會話期內有效,屬于用戶的當前會話;請求對象中的共享對象在一個請求期內有效,屬于用戶發送的當前請求;頁面對象中的共享對象只屬于當前頁面的執行實例。本文主要分析共享對象的設置和訪問方法,包括共享對象的有效范圍、具體訪問方法、輔助顯示手段和多線程下的實現策略。

    在JSP中訪問共享對象


    Servlet運行時已經準備好了這些范圍對象,如表1所示。

    表1 JSP中的共享對象


       變量名 變量類名 對象可訪問范圍
    頁面 pageContext javax.servlet.jsp.PageContext 在執行某一個JSP時,Servlet運行時會為它初始化pageContext變量,這個變量可以被整個JSP代碼訪問,包括INCLUDE指示符插進來的代碼。
    請求 ruquest javax.servlet.http.HttpServletRequest 用戶提交一個HTTP請求給Servlet容量,Servlet運行時會把請求封裝成HttpServletRequest的一個實例,在JSP中表現為request變量。能訪問pageContext的JSP代碼也能訪問request,另外被處理這個請求的JSP代碼FORWARD到的JSP代碼也能訪問。
    會話 session javax.servlet.http.HttpSession 一個HttpSession會話由被創建到關閉或失效期間的用戶請求組成。處理這些請求的JSP可以訪問到這期間的session對象中的共享對象。在會話關閉或失效時,這些對象會丟失。
    應用程序 application javax.servlet.ServletContext 這個對象在應用程序的整個生命周期間都有效,存放在這個對象內的數據任何JSP都能訪問到。



    在Servlet中訪問共享對象


    Servlet中的共享對象如表2。

    表2 Servlet中的共享對象


    請求 SERVLET類的一系列服務方法的request參數。 javax.servlet.http.HttpServletRequest 用戶提交一個HTTP請求給Servlet容器,Servlet運行時會把請求封裝成HttpServletRequest的一個實例,并作為Servlet服務方法的request參數傳遞給Servlet。這個Servlet也可以把這個實例傳遞給其它Web組件。
    會話 request.getSession()或者request.getSession(boolesn)方法獲得。 javax.servlet.http.HttpSession 一個HttpSession會話由被創建到關閉或失敗期間的用戶請求組成。處理這些請求的Servlet可以訪問到這期間的session對象中的共享對象。在會話關閉或失效時,這些共享對象會丟失。
    應用程序 SERVLET的.getServletContext() javax.servlet.ServletContext 這個對象在應用程序的整個生命周期間都有效,存放在這個對象內的數據任何Web組件都能訪問到。



    資源組合


    在JSP技術中,有兩種把資源片斷組合成一個資源的技術:include 指示符和jsp:include元素。指示符的語法為:

    
    <%@ include file="fragmentresource.jsp" %>
    


    當一個JSP被翻譯成Servlet時,它會被處理。jsp:include元素的語法是:

    
    <jsp:include page="included.jsp"/>
    


    當這個JSP頁面被執行時,它會被處理。指示符是代碼的組合,元素則是結果的組合。fragmentresource.jsp和主頁面具有一樣的上下文,如頁面對象;而included.jsp不具有和主頁面一樣的頁面對象,但請求對象是同一個。

    在Servlet中,RequestDispatcher.include(request,response)實現結果的整合,示例代碼如下:

    
    RequestDispatcher dispatcher =request.getRequestDispatcher("/template.jsp");
    if (dispatcher !=null)
     dispatcher.include(request,response);
    


    控制傳遞


    在利用RequestDispatcher.forware(request,response)把控制傳給另一個Web組件設置形成一個控制管道時,要嚴格遵循“前面的組件處理request,最后的組件處理response”的準則。前面的組件甚至不能企圖獲取response輸出流的引用。這個控制管道中的組件具有同一個request對象,不具有相同的pageContext對象(針對JSP)。Servlet中傳遞控制的例子如下:

    
    RequestDispatcher dispatcher =request.getRequestDispatcher("/template.jsp");
    if (dispatcher !=null)
    dispatcher.forward(request,response);
    


    JSP中傳遞控制的例子如下:

    
    <jsp:forward page="/main.jsp"/>
    


    在JSP中,可以通過jsp:param元素來增加請求對象的參數,適用于jsp:include和jsp:forward兩元素。 示例如下:

    
    <jsp: forward page="included.jsp">
    <jsp:param name="param1 " value=="value1"/>
    </jsp:include>
    


    顯示共享對象




    圖1 顯示共享信息類圖


    在網頁上顯示各個級別的共享對象是一個非常不錯的調試手段。下面的顯示共享對象類圖(如圖1)實現了這個功能。它以類org.i18.struts.AttributeUtils為核心,這個類負責把四個對象的共享對象保存為鍵/值對的HashMap對象。通過它可以得到請求對象中的共享對象及參數信息,以及頁面對象、會話對象、應用對象這些共享對象的函數接口。在JSP頁面中,通過下面的代碼可以給這個類的對象提供輸入:

    
    <jsp:useBean id="bean3" scope="application"
    class="org.i18.struts.AttributeUtils" />
    <jsp:setProperty name="bean0" property="object" value="<%= pageContext %>" />
    


    JSP頁面可以利用Struts提供的logic標簽庫顯示這些共享對象:

    
    <li> 這是頁對象內的共享對象 </li>
    <table align="center" cellpadding="5" border="0">
    <tbody valign="center">
    <tr>
    <td class="header"> 共享對象名 </td>
    <td class="header"> 共享對象相關內容 </td>
    </tr>
     <logic:iterate id="element" name="bean0" property="pageProp"  >
    <tr><td>
     <bean:write name="element" property="key"/>
    </td>
    <td>
    <bean:write name="element" property="value"/>
    </tr>
    </logic:iterate>
    </tbody>
    </table>
    


    在Servlet中,AttributeDisplayHelper幫助者類完成JSP中logic標簽庫相應的功能。幫助者類完成工作后,AttrServlet把幫助者類完成的結果放在request中的一個共享屬性Attr中,接著把控制傳給servletAttr.jsp,再由它訪問AttrServlet在request中設置的共享屬性Attr,并顯示結果。

    使用者可以通過attr.jsp、AttrServlet的url映射和index.jsp的提交按鈕來查看當前上下文所有級別的共享對象。

    關于多線程問題


    J2EE系列規范中,EJB規范保證了組件開發者在單線程的環境下編程,但Servlet規范沒有規定Servlet的系列服務方法在單線程模式下運作,所以開發者在使用共享對象時要注意線程同步問題。一個比較通用的原則是:在一個專職的組件中設置共享對象,當設置和訪問破壞數據的一致性時,使用Java的同步控制。

    一個Servlet(包括JSP)的生命周期由其所在的容器控制。當有一個Servlet請求時,容器執行如下步驟:

    1.如果此Servlet的實例不存在,容器先裝載Servlet的類代碼,創建一個Servlet實例,接著調用這個實例的init方法。

    2.如果此Servlet的實例存在,容器分配一個處理用戶請求的工作線程。如果Servler實現了SingleThreadModel接口,工作線程會在這個實例上同步,并且在取得訪問權限后調用實例的service方法,否則直接調用實例的service方法。javax.servlet.http.HttpServlet的service方法會根據用戶的HTTP請求類型調用相應的doxxx方法。

    3.只有當所有的線程從這個實例中退出,容器在回收這個實例時才會調用這個實例的destroy方法。

    Servlet實例線程圖(如圖2)體現了這個生命周期模型。



    圖2 Servlet實例線程圖


    雖然可以讓所有的Servlet實現SingleThreadModel接口,但這會嚴重影響程序的性能。要解決多線程的同步問題,我們首先要分析共享對象的訪問模式。在一個Web程序中,共享對象按訪問模式可以分為以下兩類:一次設置、多次讀取的共享對象和多次設置、多次讀取的共享對象。

    一次設置、多次讀取

    對于這種共享對象,可以開發一個事件監聽器,監聽程序啟動和停止事件,代碼如下:

    
    package org.i18.listen
    import org.i18.utils.*;
    import javax.servlet.*;
    import util.Counter;
    public final class ContextListener implements ServletContextListener {
     private ServletContext context =null;
     public void contextInitialized(ServletContextEvent event){
      context =event.getServletContext();
      SynObject synObject = new SynObject();
      //在這里把共享對象放在應用對象中
      context.setAttribute("SYNOBJECT",synObject);
     }
     public void contextDestroyed(ServletContextEvent event){
      context =event.getServletContext();
      //清除保存在應用對象中的共享屬性
      context.removeAttribute("SYNOBJECT ");
     }
    }
    


    這樣,當Web應用程序啟動時,容器會調用監聽器,從而設置共享對象。共享對象的訪問只需直接調用getAttribute方法即可。

    多次設置、多次讀取

    對于多次設置、多次讀取的共享對象,必須利用Java的同步機制,訪問步驟如下:

    第一步,首先設計一個同步類。這個同步類的代碼非常簡單:

    
    package org.i18.utils
    public final class SynObject{
    }
    


    以上代碼可以看出,它其實什么都沒做,但繼承了Object關于同步的方法和機制。

    第二步,把這個類的實例放到應用對象中作為一個共享對象。可以看出這個同步對象屬于一次設置、多次使用的共享對象。在應用程序啟動事件監聽器中設置它,請參見前面的代碼。

    第三步,設置共享對象。如果有對象需要整個應用程序共享,可以在Servlet的service中利用同步機制來設置:

    
    public void doGet (HttpServletRequest request,HttpServletResponse response)
    throws ServletException,IOException {
     ServletContext context=   getServletContext();
     //得到同步對象
     Object obj = context.getAttribute("SYNOBJECT");  
     //獲取同步鑰匙
     synchronized(obj){
      //先檢查是否存在這個共享對象
      Object obj2 = context.getAttribute("Attr");
      if (obj2 == null) {
       //不存在,設置共享對象
       obj2 = new TestBean();
       context.setAttribute("Attr",obj2);
      }
     }
    }
    


    第四步,讀取共享對象。當需要訪問多次設置、多次訪問的共享對象時,同樣需要利用同步機制,代碼如下:

    
    public void doGet (HttpServletRequest request,HttpServletResponse response)
    throws ServletException,IOException {
     ServletContext context=   getServletContext();
     //得到同步對象,因為這個對象是一次設置、多次讀取型的,不需要同步
     Object obj = context.getAttribute("SYNOBJECT");  
     //獲取同步鑰匙
     synchronized(obj){
      //得到需要的共享對象
      Object obj2 = context.getAttribute("Attr");
     }
    }
    


    會話對象內共享對象的多線程問題可以和應用對象一樣處理。請求對象和頁面對象正常情況下是線程安全的,除非開發者自己引入了額外的線程。

    本文分析了開發好的J2EE應用必須掌握的、組件間對象共享的技術,這種分析技術同樣適用于EJB中。在EJB容器中,信息存放的位置變成了實現JNDI的服務提供者,大家通過JNDI的接口方法查詢、綁定共享對象。需要注意的是,同步對象不能在JNDI中實現,因為大家搜索出來的不是同一個內存對象。

    posted on 2005-04-08 14:41 笨笨 閱讀(612) 評論(0)  編輯  收藏 所屬分類: J2EEALLStruts
    主站蜘蛛池模板: 亚洲欧美日韩一区二区三区 | 久青草视频97国内免费影视| 亚洲一区二区影视| 怡红院亚洲怡红院首页| 卡一卡二卡三在线入口免费| 国产在线一区二区综合免费视频| 色视频在线观看免费| 亚洲a级成人片在线观看| 亚洲精品V欧洲精品V日韩精品 | 亚洲一级免费毛片| 久久精品国产亚洲综合色| 免费人成年激情视频在线观看 | 亚洲高清毛片一区二区| 久久精品亚洲AV久久久无码| 在线免费观看亚洲| 久久久青草青青亚洲国产免观| 亚洲av无码乱码在线观看野外| 宅男666在线永久免费观看| 中文字幕无码不卡免费视频| 久久久久国色av免费看| 99免费在线视频| 一道本在线免费视频| 爱情岛亚洲论坛在线观看 | 免费观看激色视频网站bd | 亚洲精品动漫在线| 色婷婷六月亚洲婷婷丁香| 亚洲AV无码成人网站久久精品大| 亚洲天堂在线视频| 亚洲精品无码日韩国产不卡?V| 国产一区二区三区无码免费| 国产美女被遭强高潮免费网站 | 亚洲精品乱码久久久久久蜜桃图片| 亚洲一级片在线播放| 亚洲午夜在线一区| 亚洲av专区无码观看精品天堂| 亚洲中文字幕在线无码一区二区| 亚洲成人高清在线观看| 亚洲国产午夜电影在线入口| 亚洲av成人一区二区三区| 亚洲日本VA中文字幕久久道具| 亚洲αⅴ无码乱码在线观看性色|