天天看點

對象中間件--CORBA開發練習

一 實習目的

通過執行個體掌握CORBA的開發過程:主要包括:接口定義;接口的對象實作;伺服器端代碼編寫;用戶端代碼編寫;CORBA Server/Client的編譯與運作;

二 實習要求

1)基于CORBA技術開發一個考試成績查詢系統,主要包括:伺服器部分:實作查詢和錄入服務;用戶端部分包括錄入和查詢部分

2)服務端使用Java編寫,使用JDBC通路資料庫;用戶端使用Java和C++分别編寫。

三 實習過程

實驗準備

1、下載下傳omniORB

https://download.csdn.net/download/qq_44859217/12412569

2、環境變量

将java/bin以及omniORB/bin配置在環境變量path中。

對象中間件--CORBA開發練習

實驗内容

A.服務接口定義,在 W o r k h o m e Work_home Workh​ome下,編寫DataService.idl,定義查詢與錄入函數.

對象中間件--CORBA開發練習

B.Java實作Corba伺服器端。

1)用以下指令生成存根與架構:

idlj -fall DataService.idl

對象中間件--CORBA開發練習
對象中間件--CORBA開發練習

2)在 W o r k h o m e Work_home Workh​ome下,建立server檔案夾,并将1)得到的存根和架構java檔案拷貝至server,并使用eclipse建立一工程,将這些檔案包含進去。

對象中間件--CORBA開發練習

3)編寫服務端服務實作,并寫main函數以啟動corba服務。

編寫的DataServiceServer.java的代碼如下:

package server;
 
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import org.omg.PortableServer.*;
import server.DBmanager;
 
//編寫相對應的服務,一定要從 _類名ImplBase繼承,并實作相應的方法
class DataServiceImpl extends DataServicePOA // 具體的服務實作
{
    private ORB orb;
 
    public void setOrb(ORB orb_val) {
        this.orb = orb_val;
    }
 
    @Override
    public void insert(String stuName, String StuNo, float score) {
        // TODO Auto-generated method stub
        DBmanager.insert(stuName, StuNo, score);
    }
 
    @Override
    public float search(String stuNo) {
        // TODO Auto-generated method stub
        return DBmanager.search(stuNo);
    }
}
 
public class DataServiceServer// 起動服務的程式
{
    public static void main(String args[]) {
        try {
            System.out.println("建立和初始化 ORB ");
            ORB orb = ORB.init(args, null);
            POA rootpoa = POAHelper.narrow(orb
                    .resolve_initial_references("RootPOA"));
            rootpoa.the_POAManager().activate();
            System.out.println("建立服務對象并将其向 ORB 注冊 ");
            DataServiceImpl dataServiceImpl = new DataServiceImpl();
            dataServiceImpl.setOrb(orb);
            // System.out.println(orb.object_to_string(sysProImpl));
            org.omg.CORBA.Object objRef = orb
                    .resolve_initial_references("NameService");
            NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
            NameComponent[] path = { new NameComponent("DataService", "") };
            org.omg.CORBA.Object ref = rootpoa
                    .servant_to_reference(dataServiceImpl);
            DataService href = DataServiceHelper.narrow(ref);
            System.out.println(orb.object_to_string(href));
            System.out.println(ncRef.getClass().toString());
            ncRef.rebind(path, href);
            System.out.println("DataServiceServer ready and waiting ...");
            orb.run();
        } catch (Exception e) {
            System.err.println("Error: " + e);
            e.printStackTrace(System.out);
        }
    }
}
           

在工程中建立DBmanager類,用來連接配接mysql資料庫,DBmanager.java的代碼如下:

package server;
 
import java.sql.*;
 
public class DBmanager {
    private static Connection conn;
    private static Statement sta;
    private static ResultSet result;
    private static String driver = "com.mysql.jdbc.Driver";
    private static String url = "jdbc:mysql://localhost:3306/mycorba";
    private static float score;
 
    public static Connection getcon() {
        Connection con = null;
        try {
            Class.forName(driver);// 注冊驅動
        } catch (ClassNotFoundException e) {
            System.out.println("未完成注冊驅動");
            e.printStackTrace();
        }
        try {
            con = DriverManager.getConnection(url, "root", "123456");// 建立連接配接
        } catch (SQLException e) {
            // TODO: handle exception
            System.out.println("未完成資料連接配接");
            e.printStackTrace();
        }
        return con;
    }
 
    public static void insert(String stuName, String StuNo, float score) {
        try {
            conn = getcon();
            String sql = "insert into mytable(stuName,stuNo,score) values(?,?,?)";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.clearBatch();
            ps.setString(1, stuName);
            ps.setString(2, StuNo);
            ps.setFloat(3, score);
            ps.addBatch();
            ps.executeBatch();
            ps.close();
            conn.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
 
    public static float search(String StuNo) {
        try {
            conn = getcon();
            String sql = "select * from mytable where StuNo=" + StuNo;
            sta = conn.createStatement();
            result = sta.executeQuery(sql);
            if (result.next()) {
                String stuName = result.getString(1);
                String stuNo = result.getString(2);
                score = result.getFloat(3);
            }
            sta.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return score;
    }
 
}

           

C.Java實作Corba用戶端。

1)在 W o r k h o m e Work_home Workh​ome下,建立java_client檔案夾,并将B的1)得到的存根和架構java檔案拷貝至java,并使用eclipse建立一工程,将這些檔案包含進去。

對象中間件--CORBA開發練習

2)編寫用戶端對查詢與錄入的調用.

package client;
 
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
 
public class DataServiceClient {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            String SetInfo, ReturnInfo, ref;
            float score = 0;
            org.omg.CORBA.Object objRef;
            DataService dataserviceRef;
            ORB orb = ORB.init(args, null);
            /*
             * if (args.length >= 1) { ref = args[0]; //System.out.println(ref);
             * } else { System.out.println("aaaaaaaaaaaaaaaaaa"); return ; }
             */
            // 下面一條語句得到的是一個NamingContext對象,并非SysProp對象
            // objRef = orb.string_to_object(ref);
            // dataserviceRef = DataServiceHelper.narrow(objRef);
            objRef = orb.resolve_initial_references("NameService");
            System.out.println(orb.object_to_string(objRef));
            NamingContext ncRef = NamingContextHelper.narrow(objRef);
            NameComponent nc = new NameComponent("DataService", "");
            NameComponent path[] = { nc };
            dataserviceRef = DataServiceHelper.narrow(ncRef.resolve(path));
            if (args.length > 1) {
                SetInfo = args[1];
            } else {
                SetInfo = "0";
            }
            System.out.println("開始調用");
            System.out.println("運作成功!");
            System.out.println("**********成績錄入**************");
            dataserviceRef.insert("zjc", "2017013204", 100);
            System.out.println("成績錄入成功!\n");
            System.out.println("**********成績查詢**************");
            String searchStuNo = "2017013204";
            float getScore =  dataserviceRef.search(searchStuNo);
            System.out.println("學号 "+searchStuNo+" 的成績為:  "+getScore);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
           

3)建立資料庫

在MySQL中建立資料庫mycobra,在資料庫中建表mytable

對象中間件--CORBA開發練習
對象中間件--CORBA開發練習
對象中間件--CORBA開發練習

D.C++實作Corba用戶端。

需要安裝vc6.0。

1)用以下指令生成存根與架構:

omniidl -bcxx DataService.idl

得到*.hh檔案和*.cc檔案,将字尾名改為*.h和*.cpp,并在*.cpp檔案中#include “.hh” 改為#include “.h”.

對象中間件--CORBA開發練習
對象中間件--CORBA開發練習
對象中間件--CORBA開發練習

2)在 W o r k h o m e Work_home Workh​ome下,建立C_client檔案夾, 并将1)所得到的檔案拷貝至C_client。使用Vc++6.0建立一工程,工程路徑指向 W o r k h o m e Work_home Workh​omeC_client,并将存根與架構程式加入工程。

對象中間件--CORBA開發練習

3)配置vc環境。

Tools–>Options選擇Directory标簽,在Include files下加入omniORB的lib和include路徑

對象中間件--CORBA開發練習

在Library files下加入omniORB的lib路徑

對象中間件--CORBA開發練習

Project–>Setting,選擇C++,分别對C++ Language,Code Generation,Preprocessor進行設定

C++ Language下勾選“Enable Exception Handling

對象中間件--CORBA開發練習

Code Generation下的Use runtime library選擇Multithreaded DLL

對象中間件--CORBA開發練習

Preprocessor添加宏定義

“WIN32,x86,_WIN32_WINNT=0x0400,NT,OSVERSION=4”

對象中間件--CORBA開發練習

選擇Link頁籤,Category選擇Input,添加庫子產品

ws2_32.lib mswsock.lib advapi32.lib omniORB410_rt.lib omniDynamic410_rt.lib omnithread33_rt.lib

填寫附加庫路徑,我的為“D:\omniORB-4.1.0\lib\x86_win32 ”

對象中間件--CORBA開發練習

4)編寫用戶端調用。

這裡的IOR要複制伺服器端産生的那個。

#include "DataService.h"
#include <stdio.h>
int main(int argc,char* argv[]){
    try{
 
        CORBA::ORB_var orb = CORBA::ORB_init(argc,argv);
 
        char* IORStr= "IOR:000000000000001449444c3a44617461536572766963653a312e3000000000010000000000000086000102000000000e3139322e3136382e302e31303500cb3f00000031afabcb000000002006e49b4200000001000000000000000100000008526f6f74504f410000000008000000010000000014000000000000020000000100000020000000000001000100000002050100010001002000010109000000010001010000000026000000020002";
 
        CORBA::Object_var obj = orb->string_to_object(IORStr);
        if(CORBA::is_nil(obj)){
            printf("Nil Score Reference");
            throw 0;
        }
        DataService_var tm = DataService::_narrow(obj);
        if(CORBA::is_nil(tm)){
            printf("Nil Score Reference");
            throw 0;
        }
        printf("成績為  %f\n ",tm->search("2017013204"));
    }catch(const CORBA::Exception&){
        printf("Exception\n");
        return 1;
    }
    return 0;
}

           

E.測試

參考corbaExample/command.txt運作程式。

1).啟動命名服務

對象中間件--CORBA開發練習

2).啟動Java伺服器端

啟動之前先要啟動MySQL,還要注意将MySQL的連接配接的jar包加入到伺服器端工程中

對象中間件--CORBA開發練習

現在啟動Java伺服器端DataServiceServer.java

對象中間件--CORBA開發練習

3).啟動Java用戶端

啟動Java用戶端DataServiceClient.java

對象中間件--CORBA開發練習

資料庫顯示

對象中間件--CORBA開發練習

4).運作C++用戶端

對象中間件--CORBA開發練習

四 遇到的問題

①jdk缺少相應的idlj.exe應用程式,就會出現下面的問題。

對象中間件--CORBA開發練習

原因可能是因為我之前的jdk版本太低或者誤删等原因,裡面沒有idlj.exe應用程式。所及解決方法就是安裝一個新版本的jdk。可以看到新版本的jdk的bin目錄裡有該應用程式。

對象中間件--CORBA開發練習

②VC6.0的閃退問題。

原因應該是window和vc的版本不相容所導緻的。

解決方法從網上下載下傳FileTool.dll檔案,并拷貝到VC安裝目錄的Common\MSDev98\AddIns 檔案夾下。然後在DOS指令下手動注冊FileTool.dll檔案(需要用管理者身份打開),運作:

regsvr32 “VC安裝路徑\Common\MSDev98\AddIns\FileTool.dll”
           

最後打開VC,點選Tools–>定制–>附加項和宏檔案–>選中 FileTool Developer Studio Add-in 複選框 ,就可以了。

對象中間件--CORBA開發練習

之後打開和添加檔案就用這兩個按鈕,千萬不能用原來的,因為還是會退出去。

③IOR問題

運作命名服務出現的DOS界面的IOR、運作服務端産生的IOR以及運作用戶端産生的IOR都不一樣,在進行c++實作用戶端的時候,需要将伺服器端産生的IOR複制進去,否則會出現查不到資料庫内容的情況。