在JSP中訪問CORBA服務對象實例

結合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):

1. module?example?{
2. ????interface?A?{
3. ????????long?AOperation(in?long?ilData);
4. ????};
5. };


   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,然後將結果返回,代碼如下:

1. ////////////////////////////////////////
2. //?文件名:apptest_impl.h
3. #ifndef?APPTEST_IMPL_H
4. #define?APPTEST_IMPL_H
5. #include?\"apptest_skel.h\"
6.
7. class?A_impl:public?POA_example::A,?PortableServer::RefCountServantBase?{
8. ????public:
9. ????????virtual?CORBA::Long?AOperation(CORBA::Long?ilData)
10. ????????????throw(CORBA::SystemException);
11. };
12.
13. #endif
14.
15. //////////////////////////////////////////////////////
16. //?文件名:apptest_impl.cpp
17. //?包含CORBA系統類庫
18. #include?<STARCORBA.h>
19. using?namespace?std;
20. #include?<apptest_impl.h>
21.
22. //?操作AOperation的實現
23. CORBA::Long?A_impl::AOperation(CORBA::Long?ilData)
24. ????????throw(CORBA::SystemException)?{
25. ????CORBA::Long?ret;
26. ????ret?=?ilData?*?2?;
27. ????return?ret;
28. }


   3.?編寫一個主程序實例化服務對象提供服務
   在主程序中,建立CORBA環境,實例化服務對象並註冊到名字服務,然後開始等待請求,代碼如下(爲了):

1. ///////////////////////////////////////////
2. //?文件名:Server.cpp
3. #include?<stdio.h>
4. #include?<STARCORBA.h>
5. #include?<STARCosNaming.h>
6. #include?<stdlib.h>
7. #include?<errno.h>
8. #include?\"apptest_impl.h\"
9. using?namespace?std;
10.
11. int?main(int?argc,?char*?argv[],?char*[])?{
12. ????CORBA::ORB_var?orb;????
13. ????orb?=?CORBA::ORB_init(argc,?argv);
14.
15. ????CORBA::Object_var?nameobj?=?
16. ????????orb?->?resolve_initial_references(\"NameService\");
17. ????CosNaming::NamingContext_var?nc?=?
18. ????????CosNaming::NamingContext::_narrow(nameobj.in());
19.
20. ????CORBA::Object_var?poaObj?=?
21. ????????orb?->?resolve_initial_references(\"RootPOA\");
22. ????PortableServer::POA_var?rootPOA?=?
23. ????????PortableServer::POA::_narrow(poaObj);
24. ????PortableServer::POAManager_var?manager?=?
25. ????????rootPOA?->?the_POAManager();
26. ????
27. ????A_impl*?AImpl?=?new?A_impl();
28. ????PortableServer::ServantBase_var?servantA?=?AImpl;
29. ????PortableServer::ObjectId_var?Aid?=?
30. ????????rootPOA?->?activate_object(servantA);
31. ????CORBA::Object_var?A?=?
32. ????????rootPOA?->?servant_to_reference(servantA);
33.
34. ????CosNaming::Name?AName;
35. ????AName.length(1);
36. ????AName[0].id?=?CORBA::string_dup(\"A\");
37. ????AName[0].kind?=?CORBA::string_dup(\"OperationA\");
38. ????nc?->?rebind(AName,?A.in());
39. ????
40. ????manager?->?activate();
41. ????orb?->?run();
42. ????
43. ????nc?->?unbind(AName);????
44. ????return?EXIT_SUCCESS;
45. }


   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):

1. /*
2. ?*?AClient.java
3. ?*/
4. package?example;
5.
6. import?org.omg.CORBA.*;
7. import?org.omg.CORBA.ORBPackage.InvalidName;
8. import?org.omg.CosNaming.*;
9. import?org.omg.CosNaming.NamingContextPackage.CannotProceed;
10. import?org.omg.CosNaming.NamingContextPackage.NotFound;
11.
12. /**
13. ?*?@author?公飛
14. ?*/
15. public?class?AClient?{
16. ????public?static?int?opA(int?num)?throws?Exception?{
17. ????????String[]?args?=?{?\"-ORBInitRef\",
18. ????????????????\"NameService=corbaloc:iiop:192.168.60.158:900/NameService\"?};
19. ????????ORB?orb?=?ORB.init(args,?null);
20. ????????org.omg.CORBA.Object?objRef;
21. ????????objRef?=?orb.resolve_initial_references(\"NameService\");
22. ????????NamingContext?ncRef?=?NamingContextHelper.narrow(objRef);
23. ????????NameComponent?nc?=?new?NameComponent(\"A\",?\"OperationA\");
24. ????????NameComponent?path[]?=?{?nc?};
25.
26. ????????org.omg.CORBA.Object?objA;
27. ????????objA?=?ncRef.resolve(path);
28. ????????A?a?=?AHelper.narrow(objA);
29.
30. ????????int?out;
31. ????????out?=?a.AOperation(num);
32. ????????return?out;
33. ????}
34. }


   JSP文件的代碼如下(index.jsp):

1. <%@?page?contentType=\"text/html;charset=gb2312\"%>
2. <%@?page?import?=?\"example.AClient\"?%>
3. <html>
4. ????<head>
5. ????????<title>Hello?JSP?CORBA?Client</title>
6. ????</head>?
7. ????<body>
8. ????????3*2=<%=AClient.opA(3)%>
9. ????</body>
10. </html>


   好了,編譯好你的程序,運行名字服務,運行CORBA服務程序,運行應用服務器InforWeb,部署Web應用,然後就可以通過瀏覽器訪問了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章