js|對象|訪問 結合J2EE和CORBA可以充分利用兩者的優點建立效能更好功能更強的應用系統,例如可以使用C++實現的CORBA對象作為業務處理構件,形成高效能商務邏輯層,在JSP中訪問CORBA構件建立展現層。 下面我們就一起來看一個在JSP中訪問CORBA服務物件的例子。
軟體選擇:
CORBA服務方,我們選擇中創軟體商用中介軟體有限公司(http://www.inforbus.com)的InforBus(一個遵循CORBA規範的分布對象中介軟體),基於C++進行開發。作業系統選擇IBM AIX(當然,你也可以選擇HP UNIX、Linux或者Windows之類的)。
CORBA客戶方,為了展現CORBA的互操作能力,這裡使用了JDK中包含的ORB。當然,作為一種更好的選擇,您也可以使用InforBus的Java版本來實現CORBA的客戶方。
JSP運行環境,我們選擇中創軟體商用中介軟體有限公司(http://www.inforbus.com)的InforWeb(一個遵循J2EE規範的應用伺服器)。作業系統選擇Window(當然,你也可以選擇HP UNIX、Linux或者AIX之類的)。
程式實現
IDL
IDL是CORBA服務方和客戶方進行請求調用的協議,只要使用相同的IDL,客戶方和服務方就可以進行無縫的通訊,而與客戶方和服務方的開發語言、作業系統都沒有關係,甚至你可以為客戶方和服務方選擇不同的CORBA中介軟體(只要他們都遵循CORBA規範)。在實現CORBA客戶方程式的時候,你不需要關心服務方的任何細節,你所需要關心的只有IDL!
在這裡我們定義如下所示的IDL(檔案名稱為apptest.idl):
- module example {
- interface A {
- long AOperation(in long ilData);
- };
- };
CORBA服務方程式實現
CORBA服務方實現需要做的工作主要有:將IDL映射到C++,實現IDL中定義的介面(即實現處理邏輯),編寫一個主程式執行個體化服務物件提供服務。
1. 將IDL映射到C++
這個只需要調用InforBus的IDL編譯器idl,執行如下命令:
idl apptest.idl
這個命令將產生四個檔案:apptest.h、apptest.cpp、apptest_skel.cpp、apptest_skel.cpp,其中包含了Skeleton。
2. 實現IDL中定義的介面
繼承Skeleton,實現IDL介面定義,在實作類別中完成你的商務邏輯,在這個例子中我們實現一個簡單的邏輯,將接收到的參數乘以2,然後將結果返回,代碼如下:
- ////////////////////////////////////////
- // 檔案名稱:apptest_impl.h
- #ifndef APPTEST_IMPL_H
- #define APPTEST_IMPL_H
- #include \"apptest_skel.h\"
- class A_impl:public POA_example::A, PortableServer::RefCountServantBase {
- public:
- virtual CORBA::Long AOperation(CORBA::Long ilData)
- throw(CORBA::SystemException);
- };
- #endif
- //////////////////////////////////////////////////////
- // 檔案名稱:apptest_impl.cpp
- // 包含CORBA系統類別庫
- #include <STARCORBA.h>
- using namespace std;
- #include <apptest_impl.h>
- // 操作AOperation的實現
- CORBA::Long A_impl::AOperation(CORBA::Long ilData)
- throw(CORBA::SystemException) {
- CORBA::Long ret;
- ret = ilData * 2 ;
- return ret;
- }
3. 編寫一個主程式執行個體化服務物件提供服務
在主程式中,建立CORBA環境,執行個體化服務物件並註冊到名字服務,然後開始等待請求,代碼如下(為了):
- ///////////////////////////////////////////
- // 檔案名稱:Server.cpp
- #include <stdio.h>
- #include <STARCORBA.h>
- #include <STARCosNaming.h>
- #include <stdlib.h>
- #include <errno.h>
- #include \"apptest_impl.h\"
- using namespace std;
- int main(int argc, char* argv[], char*[]) {
- CORBA::ORB_var orb;
- orb = CORBA::ORB_init(argc, argv);
- CORBA::Object_var nameobj =
- orb -> resolve_initial_references(\"NameService\");
- CosNaming::NamingContext_var nc =
- CosNaming::NamingContext::_narrow(nameobj.in());
- CORBA::Object_var poaObj =
- orb -> resolve_initial_references(\"RootPOA\");
- PortableServer::POA_var rootPOA =
- PortableServer::POA::_narrow(poaObj);
- PortableServer::POAManager_var manager =
- rootPOA -> the_POAManager();
-
- A_impl* AImpl = new A_impl();
- PortableServer::ServantBase_var servantA = AImpl;
- PortableServer::ObjectId_var Aid =
- rootPOA -> activate_object(servantA);
- CORBA::Object_var A =
- rootPOA -> servant_to_reference(servantA);
- CosNaming::Name AName;
- AName.length(1);
- AName[0].id = CORBA::string_dup(\"A\");
- AName[0].kind = CORBA::string_dup(\"OperationA\");
- nc -> rebind(AName, A.in());
-
- manager -> activate();
- orb -> run();
-
- nc -> unbind(AName);
- return EXIT_SUCCESS;
- }
Web應用實現
Web應用中主要是通過一個JSP訪問CORBA服務物件並進行展示,在這裡充當CORBA的客戶方。實現Web應用需要完成兩個方面任務:將IDL映射到Java,在JSP中發送請求並展示結果。
1. 將IDL映射到Java
這個只需要調用JDK的IDL編譯器idlj,執行如下命令:
idlj apptest.idl
這個命令將產生五個檔案:A.java、AOperations.java、AHelper.java、AHolder.java和_AStub.java,其中包含了Stub。
2. 在JSP中發送請求並展示結果。
為了避免在JSP中包含太多的Script,在這裡將發送請求的代碼從JSP分離到了一個簡單的Java類中。
Java類的代碼如下(AClient.java):
- /*
- * AClient.java
- */
- package example;
- import org.omg.CORBA.*;
- import org.omg.CORBA.ORBPackage.InvalidName;
- import org.omg.CosNaming.*;
- import org.omg.CosNaming.NamingContextPackage.CannotProceed;
- import org.omg.CosNaming.NamingContextPackage.NotFound;
- /**
- * @author 公飛
- */
- public class AClient {
- public static int opA(int num) throws Exception {
- String[] args = { \"-ORBInitRef\",
- \"NameService=corbaloc:iiop:192.168.60.158:900/NameService\" };
- ORB orb = ORB.init(args, null);
- org.omg.CORBA.Object objRef;
- objRef = orb.resolve_initial_references(\"NameService\");
- NamingContext ncRef = NamingContextHelper.narrow(objRef);
- NameComponent nc = new NameComponent(\"A\", \"OperationA\");
- NameComponent path[] = { nc };
- org.omg.CORBA.Object objA;
- objA = ncRef.resolve(path);
- A a = AHelper.narrow(objA);
- int out;
- out = a.AOperation(num);
- return out;
- }
- }
JSP檔案的代碼如下(index.jsp):
- <%@ page contentType=\"text/html;charset=gb2312\"%>
- <%@ page import = \"example.AClient\" %>
- <html>
- <head>
- <title>Hello JSP CORBA Client</title>
- </head>
- <body>
- 3*2=<%=AClient.opA(3)%>
- </body>
- </html>
好了,編譯好你的程式,運行名字服務,運行CORBA服務程式,運行應用伺服器InforWeb,部署Web應用,然後就可以通過瀏覽器訪問了。