小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

J2EE的客戶端

 fondofbeyond 2007-10-07
這篇文章試圖從J2EE客戶端的角度出發(fā)來介紹J2EE體系。將介紹J2EE的客戶端如何對EJB進行訪問。J2EE的客戶端分類。最后重點分析J2EE中兩種相似的客戶端Stand alone Client與J2EE Application Client。并會給出針對同一個Stateless Session Bean的這兩種不同客戶端的實現(xiàn)實例來具體說明它們的異同。

本文的所有實例都基于SUN的J2EE SDK進行發(fā)布。附錄中也會對SUN的這個非常方便我們學(xué)習(xí)J2EE的開發(fā)工具集進行介紹。

J2EE客戶端簡介

J2EE的客戶端,簡單的說就是所有針對EJB而言都處于客戶調(diào)用邏輯的組件與程序。因為J2EE結(jié)構(gòu)的復(fù)雜性,J2EE客戶端也比較多,一般分為以下五種。Stand Alone Client,J2EE Application Client,JSP,Servlets,其它Enterprise JavaBeans(處于客戶邏輯的EJB)。

這其中,大家對JSP與Servlets可能是比較熟悉的,因為現(xiàn)在基于J2EE的應(yīng)用開發(fā)大部分是Broswer/Server模式,所以它們也是最常用的J2EE的客戶端。而EJB本身起到客戶端作用,我們也會經(jīng)常碰到,比如在Session Bean中調(diào)用Entity Bean中的商業(yè)方法,那么Session Bean 就是這個Entity Bean的客戶端。

談到J2EE就不能不提到EJB。EJB是J2EE結(jié)構(gòu)的核心,我們在它里面實現(xiàn)商業(yè)邏輯,而由實現(xiàn)J2EE結(jié)構(gòu)的服務(wù)平臺提供商為我們提供J2EE Server、EJB Container、Web Container,從而為我們提供諸如安全控制、事務(wù)處理、客戶連接、以及數(shù)據(jù)庫訪問這些服務(wù)。這樣通過對整個體系劃分出不同的角色(如應(yīng)用開發(fā)者,J2EE服務(wù)器提供商等等),讓我們這些開發(fā)者可以專心于商業(yè)邏輯的實現(xiàn),并能最大限度的實現(xiàn)代碼的可復(fù)用性。

在EJB1.1規(guī)范中有兩種EJB,一種是Session Bean另一種是Entity Bean。這兩種EJB也是我們最常用到的。不論是Session Bean 還是Entity Bean它們在實現(xiàn)上都是由三部分組成。首先是Remote Home Interface,在這個遠程接口中定義的是可由客戶端調(diào)用的創(chuàng)建、查找(對Entity Bean而言)EJB的方法。然后是Remote Interface,這個遠程接口中定義的是可供客戶端訪問的商業(yè)方法。最后是Bean Class,這個類對客戶端而言是不可訪問的,在這個類中我們要具體實現(xiàn)相應(yīng)的商業(yè)方法,以及一些供EJB Container調(diào)用的方法。對Session Bean 與Entity Bean,以及對Entity Bean 中的bmp模式以及cmp模式而言,這個類會有很大的不同。但這不是這篇文章要重點介紹的,你只要記住對J2EE的客戶端,能看到的只是Remote Interface與Remote Home Interface這兩個接口而已。下面讓我們看看客戶端是如何具體完成對EJB的訪問的。





回頁首


客戶端如何訪問EJB

不論是那種J2EE的客戶端,它要調(diào)用一個EJB的相應(yīng)商業(yè)方法都要經(jīng)過以下這三步:

1、 通過JNDI定位EJB的Remote Home Interface 創(chuàng)建JNDI名稱環(huán)境,通過在發(fā)布時你給EJB定義的JNDI名稱找到該EJB的Remote Home Interface。

2、 創(chuàng)建EJB的實例,得到Remote Interface 調(diào)用上一步得到的Remote Home Interface中的create()方法,EJB Container會創(chuàng)建相應(yīng)EJB的實例。而你得到的就是一個定義了EJB要實現(xiàn)的商業(yè)方法的Remote Interface。(EJB Container創(chuàng)建EJB實例的基本過程如下:客戶端調(diào)用create()方法-'EJB Container實例化相應(yīng)的EJB Bean Class'EJB Container調(diào)用Bean Class中的ejbCreate方法'最后返回給我們的是EJB的Remote Interface)

3、 調(diào)用Remote Interface中的商業(yè)方法 客戶端調(diào)用上一步創(chuàng)建的Remote Interface中的商業(yè)方法,EJB Container就會調(diào)用相應(yīng)Bean Class實例中的相應(yīng)方法。

下面讓我們通過具體的代碼來說明這個過程。首先我們先來創(chuàng)建一個Stateless Session Bean。這個Session Bean實現(xiàn)的功能很簡單,在其中的商業(yè)方法只有一個sayHello方法,打印一句"Hello World:"。如我上邊所介紹的這個EJB共有三個部分,它們的源代碼如下所示:

包括create()方法的Remote Home Interface接口:

package com.javausr.example;
                                    import java.rmi.*;
                                    import javax.ejb.*;
                                    public interface HelloWorldHome extends EJBHome {
                                    public HelloWorld create() throws RemoteException, CreateException;
                                    }


定義商業(yè)方法的Remote Interface接口:

        package com.javausr.example;
                                    import java.rmi.*;
                                    import javax.ejb.*;
                                    public interface HelloWorld extends EJBObject {
                                    public void sayHello() throws RemoteException;
                                    }


實現(xiàn)商業(yè)方法的Bean Class :

        package com.javausr.example;
                                    import java.rmi.*;
                                    import javax.ejb.*;
                                    public class HelloWorldBean implements SessionBean {
                                    private SessionContext sessionContext;
                                    public void ejbCreate() {}
                                    public void ejbRemove() throws RemoteException {}
                                    public void ejbActivate() throws RemoteException {}
                                    public void ejbPassivate() throws RemoteException {}
                                    public void setSessionContext(SessionContext sessionContext) throws
                                    RemoteException {
                                    this.sessionContext = sessionContext;
                                    }
                                    /**唯一的商業(yè)方法*/
                                    public void sayHello(){
                                    System.out.println("Hello :)");
                                    }
                                    }


有了具體的EJB后,我們就可以看看在J2EE客戶端是如何具體完成上邊三步的。首先,我們通過JNDI得到HelloWorldHome接口,這個過程又分為以下幾步:

  1. 創(chuàng)建一個JNDI的名稱環(huán)境: 
    Context ctx = new InitialContext(); 
    我這里的例子使用SUN的J2EE SDK1.3發(fā)布。在這個發(fā)布環(huán)境下,創(chuàng)建JNDI的名稱環(huán)境不需要任何參數(shù),因為這些參數(shù)都在系統(tǒng)啟動時被自動設(shè)置好了。但如果你使用WEBLOGIC或者其它的應(yīng)用服務(wù)器,就需要指定Context.INITIAL_CONTEXT_FACTORY以及Context.PROVIDER_URL參數(shù)來創(chuàng)建這個初始的名稱環(huán)境(有過JNDI的詳細情況,可以參考SUN的JNDI 部分)。
  2. 通過發(fā)布時指定給EJB的JNDI名稱,得到我們需要的對象: 
    Object ref = ctx.lookup("HelloWorld"); 
    這里我給這個EJB起的JNDI名字是HelloWorld。
  3. 下面我們要將上一步得到的對象造型成HelloWorldHome對象: 
    HelloWorldHome helloWorldHome= (HelloWorldHome)PortableRemoteObject.narrow(ref, HelloWorldHome.class); 
    因為得到的是遠程對象,所以這里我們要用javax.rmi.PortableRemoteObject中的方法對我們得到的對象進行造型。

 

在我們得到了EJB的Remote Home Interface后,我們通過其中的create()方法創(chuàng)建一個EJB實例,并得到Remote Interface。代碼如下: HelloWorld helloWorld = helloWorldHome.create();

現(xiàn)在我們就可以通過上一步得到的Remote Interface來調(diào)用我們想調(diào)用的商業(yè)方法。這里我們的EJB只實現(xiàn)了一個sayHello()方法。用如下的代碼完成對它的調(diào)用: helloWorld.sayHello();

所有的客戶端訪問EJB都是要經(jīng)過以上這些步驟。Servlets一般在它的init()方法中完成創(chuàng)建EJB實例的步驟。而JSP訪問EJB,最好都通過Java Beans來實現(xiàn),所以一般在相應(yīng)Java Bean的初始化方法中完成創(chuàng)建EJB的步驟。當然你也可以根據(jù)自己的需要在任意地點完成這些步驟。

這篇文章試圖從客戶端的角度來向大家介紹J2EE結(jié)構(gòu),而不是只對客戶端進行介紹。所以在這里還有一些其他的信息希望大家能了解一下。在EJB2.0規(guī)范中,有一些新的情況出現(xiàn)了,可以對EJB進行本地訪問(Local Access)。實現(xiàn)了本地訪問的EJB像實現(xiàn)了遠程訪問的EJB一樣有兩個接口供客戶端訪問。一個是Local Interface它像Remote Interface一樣定義要實現(xiàn)的商業(yè)邏輯。一個是Local Home Interface,它提供創(chuàng)建EJB以及查找(對Entity Bean而言)方法,就像Remote Home Interface一樣。這兩個Local Interface是供客戶端訪問而用,而對EJB的實現(xiàn)仍然在Bean Class中。對客戶端而言,如果它要訪問一個只有本地接口的EJB,那么它必須要和這個EJB在同一個java虛擬機中。而對一個實現(xiàn)遠程接口的EJB,當然沒有這樣的限制。本地訪問會提高系統(tǒng)性能,而且在一些場和你必須要讓EJB實現(xiàn)本地訪問(如container-managed relationship中目標端的Entity Bean,詳情請參考EJB2.0規(guī)范。一般只是在Entity Bean中實現(xiàn)本地訪問接口)。

這樣設(shè)計一個EJB時你要考慮是實現(xiàn)遠程還是本地訪問。如果你所有的組件如EJB、WEB、J2EE Client等只是發(fā)布于同一臺機器上,那么你就可以選擇為EJB實現(xiàn)本地接口(當然還有一些必須實現(xiàn)本地接口的情況)。如果你要考慮分布式的情況,那么實現(xiàn)遠程訪問接口是你唯一的選擇。如果你的EJB使用本地訪問的話,對客戶端就有了一些新的變化??蛻舳嗽L問實現(xiàn)了本地接口EJB的流程和上面介紹的訪問實現(xiàn)遠程接口EJB的過程基本一樣。但在通過EJB的JNDI名稱得到EJB的對象后,對其造型成相應(yīng)EJB的Local Home接口時,不需要再使用javax.rmi.PortableRemoteObject中的方法,而是直接用相應(yīng)對象類型造型。假設(shè)我們上邊的EJB實現(xiàn)的是本地訪問接口,那么相應(yīng)客戶端訪問代碼如下:

	Context ctx = new InitialContext();
                                    Object ref = ctx.lookup("HelloWorld");
                                    HelloWorldHome helloWorldHome=(HelloWorldHome)ref ;
                                    


還有在EJB2.0中出現(xiàn)了一種新的EJB:Message-Driven Bean。這種新的EJB類型和其他兩種有很大不同。首先,它不像其它兩種EJB那樣有自己的供客戶端調(diào)用的Remote或者Local Interface,它只有一個Bean Class。而且客戶端也無法定位及調(diào)用Message-Driven Bean中的方法。對客戶端而言它是不可見的。

下面詳細介紹一下J2EE中的兩種客戶端,Stand alone Client與J2EE Application Client。





回頁首


Stand alone Client

這種客戶端就如它的名字一樣,它獨立于J2EE,不是J2EE的組件。它一般用于測試我們開發(fā)的EJB。下面是一個具體的例子,它訪問的EJB是上邊的那個Stateless Session Bean。

import javax.naming.Context;
                                    import javax.naming.InitialContext;
                                    import javax.rmi.PortableRemoteObject;
                                    import com.javausr.example.HelloWorld;
                                    import com.javausr.example.HelloWorldHome;
                                    public class MyStandAloneClient {
                                    public static void main(String[] args) {
                                    try {
                                    //創(chuàng)建jndi初始化環(huán)境
                                    Context initial = new InitialContext();
                                    //找到ejb的Remote Home Interface
                                    Object objref = initial.lookup("HelloWorld");
                                    HelloWorldHome home =
                                    (HelloWorldHome)PortableRemoteObject.narrow(objref,
                                    HelloWorldHome.class);
                                    //初始化ejb,得到Remote Interface
                                    HelloWorld helloWorld = home.create();
                                    //調(diào)用商業(yè)方法sayHello()
                                    helloWorld.sayHello();
                                    System.exit(0);
                                    } catch (Exception ex) {
                                    System.err.println("Caught an unexpected exception!");
                                    ex.printStackTrace();
                                    }
                                    }
                                    }

打開一個dos窗口,使用如下的指令編譯我們的代碼(請根據(jù)自己的環(huán)境對里面的參數(shù)作相應(yīng)調(diào)整): 
D:\j2sdkee1.3\myapp\HELLOW~1>javac -classpath .;d:\j2sdkee1.3\lib\j2ee.jar MyStandAloneClient.java

編譯完成后在運行這個例子之前,要在我們的J2EE 服務(wù)器上發(fā)布我們所實現(xiàn)的EJB。這里我使用的J2EE服務(wù)器是J2EE SDK 1.3,有關(guān)它的介紹請見本文的附錄1--J2EE SDK1.3介紹。如何在它上邊發(fā)布HelloWorld EJB的詳細步驟請見附錄2--發(fā)布HelloWorld Staless Session Bean。

在服務(wù)器已經(jīng)啟動,EJB已經(jīng)發(fā)布的情況下,讓我們來運行一下上邊的例子,使用如下的命令運行: 
D:\j2sdkee1.3\myapp\HELLOW~1>java -classpath ".;d:\j2sdkee1.3\lib\j2ee.jar;helloworldClient.jar" MyStandAloneClient

這樣你就可以在J2EE Server控制臺上看到我們的MyStandAloneClient調(diào)用sayHello方法所打印出來的"Hello :)"(使用j2ee -verbose啟動服務(wù)器)。





回頁首


J2EE Application Client

它和Stand alone Client很像,也是一個java application,但不同的是這種客戶端是J2EE組件的一種。所以要想使用這種客戶端,你就要用相應(yīng)J2EE服務(wù)器的應(yīng)用發(fā)布工具將它發(fā)布到服務(wù)器上。因為它是J2EE的組件,它與Stand alone Client最大不同在于它可以使用J2EE提供的服務(wù)。比如它可以由J2EE統(tǒng)一進行安全認證,在你運行J2EE Application Client時系統(tǒng)會自動彈出一個認證窗口,你輸入J2EE服務(wù)器上許可的用戶名和密碼后才能運行這個程序,從而訪問J2EE Server上的EJB。它給我們開發(fā)帶來的好處是可想而知的。

還有在J2EE Application Client中,你可以通過為已有的EJB加入JNDI參考來用自己定義的JNDI名稱訪問EJB。例如在我的例子中是通過下面的代碼來得到EJB對象的: Object objref = initial.lookup("java:comp/env/ejb/hai");

大家也許記得在Stand alone Client例子中,我是通過"HelloWorld"JNDI名稱得到同樣的對象的。而這里卻是"ejb/hai"。用不同的JNDI名稱來訪問同一個EJB。這樣做的好處就是你可以隨意更改你的EJB的JNDI名稱,而J2EE Application Client程序代碼不需要有任何更改,只需要修改EJB參考中的對應(yīng)關(guān)系就可以了。這里是源代碼:

import javax.naming.Context;
                                    import javax.naming.InitialContext;
                                    import javax.rmi.PortableRemoteObject;
                                    import com.javausr.example.HelloWorld;
                                    import com.javausr.example.HelloWorldHome;
                                    public class MyJ2EEAPPClient {
                                    public static void main(String[] args) {
                                    try {
                                    //創(chuàng)建jndi初始化環(huán)境
                                    Context initial = new InitialContext();
                                    //找到ejb的Remote Home Interface
                                    Object objref = initial.lookup("java:comp/env/ejb/hai");
                                    HelloWorldHome home =
                                    (HelloWorldHome)PortableRemoteObject.narrow(objref,
                                    HelloWorldHome.class);
                                    //初始化ejb,得到Remote Interface
                                    HelloWorld helloWorld = home.create();
                                    //調(diào)用商業(yè)方法sayHello()
                                    helloWorld.sayHello();
                                    System.exit(0);
                                    } catch (Exception ex) {
                                    System.err.println("Caught an unexpected exception!");
                                    ex.printStackTrace();
                                    }
                                    }
                                    }
                                    


你會發(fā)現(xiàn)在代碼上除了上面提到的JNDI名稱不同外,沒有其他什么不同。但是我們不能像對Stand alone Client那樣,編譯完后就運行它,而要先創(chuàng)建一個J2EE Application Client組件,并把它加入到我們的應(yīng)用中。有關(guān)這個創(chuàng)建過程請參考文章附錄3--創(chuàng)建J2EE Application Client組件。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多