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

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

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

    如鵬網(wǎng) 大學(xué)生計(jì)算機(jī)學(xué)習(xí)社區(qū)

    CowNew開源團(tuán)隊(duì)

    http://www.cownew.com 郵件請(qǐng)聯(lián)系 about521 at 163.com

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      363 隨筆 :: 2 文章 :: 808 評(píng)論 :: 0 Trackbacks
     

      近日(呵呵,這篇文章是去年寫的)用了兩個(gè)月開發(fā)了一個(gè)物流信息系統(tǒng),這個(gè)系統(tǒng)是兩層、三層相結(jié)合,C/SB/S相結(jié)合的系統(tǒng)。雖然限于時(shí)間的緊張和人手的原因,系統(tǒng)規(guī)模不是很大,但是其中涉及的技術(shù)卻很全面。在這個(gè)《開發(fā)技術(shù)篇》中我們將講解我在開發(fā)系統(tǒng)中遇到的技術(shù)問題及解決方案,希望對(duì)大家有幫助。對(duì)于物流信息系統(tǒng)的分析設(shè)計(jì)問題,我將在另一篇文章《物流信息系統(tǒng)開發(fā)手記――系統(tǒng)構(gòu)架篇》中講解。

     

    一、Midas的安全問題。

        Midas技術(shù)是Delphi中進(jìn)行三層開發(fā)的首選技術(shù),它不僅有純DCOM/COM+(COM+技術(shù)是.NET技術(shù)的基礎(chǔ))的優(yōu)點(diǎn),而且也結(jié)合了Delphi的快速開發(fā)特性,可以快速開發(fā)出想要的系統(tǒng),其開發(fā)速度是用VC,PB等開發(fā)DCOM的數(shù)十倍,把程序員從煩雜的代碼中解脫出來,從而將更多的精力投入到業(yè)務(wù)邏輯的設(shè)計(jì)中去。

        但是Midas技術(shù)的一個(gè)最令人擔(dān)憂的就是它的安全問題:

    遠(yuǎn)端只要知道應(yīng)用服務(wù)器的端口號(hào)即可訪問到應(yīng)用服務(wù)器,而一旦訪問到應(yīng)用服務(wù)器,TClientDataSet即可獲得ProviderNames列表。一旦知道了ProviderNames列表,這就相當(dāng)于將數(shù)據(jù)庫(kù)暴露在外了。

    關(guān)于可輕易獲得ProviderNames列表的問題,我使用下面的方法解決:

     在服務(wù)器端定義一個(gè)

    LoginMTS(const AUserId, APassword: WideString): WordBool;

    方法。初始狀態(tài)下,所有的DataSetProvider和數(shù)據(jù)集的連接斷開。用戶必須調(diào)用LoginMTS并傳遞用戶名和密碼,登陸成功才將DataSetProvider和數(shù)據(jù)集的連接打開。這樣如果用戶驗(yàn)證沒有通過,即使它獲得了ProviderNames列表也沒法調(diào)用接口中的方法對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。

    二、Midas中主從表的實(shí)現(xiàn)

    主從表的應(yīng)用在信息系統(tǒng)中應(yīng)用很廣。在兩層開發(fā)中我們可以通過直接建立兩個(gè)數(shù)據(jù)集之間為主從關(guān)系來實(shí)現(xiàn)主從表;在三層中雖然我們?nèi)匀豢梢酝ㄟ^直接建立兩個(gè)數(shù)據(jù)集之間為主從關(guān)系來實(shí)現(xiàn)主從表,但是這樣就要求把數(shù)據(jù)庫(kù)中所有相關(guān)的數(shù)據(jù)行都下載到本地,喪失了三層開發(fā)的優(yōu)勢(shì)。我在實(shí)際中使用下面的方法實(shí)現(xiàn)。這里我以實(shí)現(xiàn)入庫(kù)單查詢、添加、修改、刪除(CRUD)為例來講解:

    1)新建一個(gè)MTS Data Module,命名為TmtsStockInListBiz,增加如下方法:

        function QueryStockInListMasterById(const AId: WideString;

          var ADatas: OleVariant): WordBool; safecall;

        function QueryStockInListSlaveByMasterId(const AId: WideString;

          var ADatas: OleVariant): WordBool; safecall;

        procedure UpdataStockInListMaster(var ADatas: OleVariant); safecall;

        procedure UpdataStockInListSlave(var ADatas: OleVariant); safecall;

        function GenerateStockInListId: WideString; safecall;

     

    QueryStockInListMasterById作用是根據(jù)入庫(kù)單單號(hào)查詢?nèi)霂?kù)單的基本信息(入庫(kù)日期、負(fù)責(zé)人等),Aid為入庫(kù)單單號(hào),Adatas為返回值,其格式就是Midas的數(shù)據(jù)包,可以將其附給ClientDatSetData屬性。

    QueryStockInListSlaveByMasterId作用是根據(jù)入庫(kù)單單號(hào)查詢?nèi)霂?kù)單的詳細(xì)信息(商品條碼,數(shù)量)

    UpdataStockInListMaster是對(duì)入庫(kù)單主表進(jìn)行刪除、添加、修改操作。只要將ClientDataSetDelta屬性做為傳遞即可。

    UpdataStockInListSlave是對(duì)入庫(kù)單從表進(jìn)行刪除、添加、修改操作。

    GenerateStockInListId是產(chǎn)生一個(gè)唯一的入庫(kù)單號(hào)。

    下面是幾個(gè)方法的代碼,都很簡(jiǎn)單,就不多解釋了,可以查看Delphi的幫助。

    function TmtsStockInListBiz.QueryStockInListMasterById(

      const AId: WideString; var ADatas: OleVariant): WordBool;

    begin

      result := false;

      ADatas := null;

      try

        cdsQuery.Close;

        cdsQuery.CommandText := 'select * from t_StockInListMaster where Id=:Id';

        cdsQuery.Params.ParamByName('Id').AsString := AId;

        cdsQuery.Open;

        if cdsQuery.RecordCount > 0 then

        begin

          result := true;

          ADatas := cdsQuery.Data;

        end;

      finally

        cdsQuery.Close;

      end;

    end;

     

    procedure TmtsStockInListBiz.UpdataStockInListMaster(

      var ADatas: OleVariant);

    var

      eCount: Integer;

      OwnerData: OleVariant;

    begin

      DCOMConStockInList.GetServer.AS_ApplyUpdates('dspStockInListMaster',

        ADatas, -1, eCount, OwnerData);

    end;

     

    function TmtsStockInListBiz.GenerateStockInListId: WideString;

    var

      LPrior: string;

      i: Integer;

    begin

      cdsQuery.Close;

      cdsQuery.CommandText := 'select top 1 id from t_StockInListMaster order by id desc';

      cdsQuery.Open;

      LPrior := cdsQuery.FieldByName('Id').AsString;

      i := StrToIntDef(RightStr(LPrior,8),0);

      Inc(i);

      result := 'RK' + FormatFloat('00000000',i);

      cdsQuery.Close;

    end;

     

    2)、新建一個(gè)應(yīng)用程序,通過DCOMConnectionSocketConnection等連接到MTS組件,然后就可以調(diào)用MTS的相應(yīng)的方法實(shí)現(xiàn)客戶端功能了。

    放入cdsStockInListMastercdsStockInListSlave兩個(gè)ClientDataSet控件,在控件上點(diǎn)擊右鍵,選擇“FieldsEditor”新建于服務(wù)器中的字段同樣的字段,然后再次在控件上單擊右鍵,選擇“CreateDataSet”,建立一個(gè)本地?cái)?shù)據(jù)庫(kù)。

    3

    根據(jù)入庫(kù)單號(hào)查詢?nèi)霂?kù)單的方法實(shí)現(xiàn):

    procedure TFormStockInList.BtnFindClick(Sender: TObject);

    var

      v,vs: OleVariant;

    begin

      if SocketConStockInList.AppServer.QueryStockInListMasterById(Trim(LEdtId.Text), v) then

      begin

        cdsStockInListMaster.Data := v;//顯示入庫(kù)單主表(主要信息)

     

        if SocketConStockInList.AppServer.QueryStockInListSlaveByMasterId(Trim(LEdtId.Text), vs) then

          cdsStockInListSlave.Data := vs; ;//顯示入庫(kù)單從表(明細(xì)信息)

      end

      else

        ShowMessage('此單不存在!');

    end;

    4)新建入庫(kù)單的實(shí)現(xiàn)

    procedure TFormStockInList.BtnNewClick(Sender: TObject);

    var

      LId: string;

    begin

      ClearCDSRecord;

      cdsStockInListMaster.Open;

      cdsStockInListMaster.Insert;

      LId := SocketConStockInList.AppServer.GenerateStockInListId;

      LEdtId.Text := LId;

      cdsStockInListMaster.FieldByName('Id').AsString := LId;

      cdsStockInListMaster.FieldByName('GenerateDate').AsDateTime := Now();

    end;

    5)提交功能的實(shí)現(xiàn)

    procedure TFormStockInList.BtnPostClick(Sender: TObject);

    var

      LQuerymts: ImtsQueryObjDisp;

      LBar: string;

    begin

      SetSocketConnectionConnect(SocketConQuery);

      LQuerymts := ImtsQueryObjDisp(SocketConQuery.GetServer);

     

      SocketConQuery.Close;

     

      if cdsStockInListMaster.RecordCount > 0 then

        SocketConStockInList.AppServer.UpdataStockInListMaster(cdsStockInListMaster.Delta);

      if cdsStockInListSlave.RecordCount > 0 then

      SocketConStockInList.AppServer.UpdataStockInListSlave(cdsStockInListSlave.Delta);

    end;

    注:本文中ClientDataSet控件的名稱開頭一般為cdsTsocketConnection控件的名稱開頭一般為SocketCon

    三、動(dòng)態(tài)設(shè)置TsimpleObjectBroker的服務(wù)器列表

    procedure SetSocketConnectionConnect(AValue: TSocketConnection);

      procedure FillAppServerList(ABroker: TSimpleObjectBroker);

      var

        sl: TStringList;

        i, n: Integer;

      begin

        sl := TStringList.Create;

        從配置文件中讀取服務(wù)器列表,并保存到sl;

        n := sl.Count - 1;

        ABroker.ServerData := null;

        for i := 0 to n do

        begin

          ABroker.Servers.Add;

          ABroker.Servers[i].ComputerName := sl.Strings[i]

        end;

        sl.Free;

      end;

    var

      LBroker: TSimpleObjectBroker;

    begin

      LBroker := TSimpleObjectBroker.Create(nil);

        FillAppServerList(LBroker);

        AValue.ObjectBroker := LBroker;

        try

          AValue.Connected := true;

        except

          raise Exception.Create('應(yīng)用服務(wù)器連接錯(cuò)誤!');

        end;

        LBroker.Free;

    end;

    posted on 2005-10-22 00:51 CowNew開源團(tuán)隊(duì) 閱讀(2261) 評(píng)論(1)  編輯  收藏

    評(píng)論

    # re: 物流信息系統(tǒng)開發(fā)手記-Delphi的三層開發(fā) 2009-12-12 15:43 hello
    想請(qǐng)教下Midas的安全問題,我認(rèn)為,

    如果有一個(gè)軟件的正常用戶用LoginMTS()登錄之后,DataSetProvider和DataSet就關(guān)聯(lián)起來了。

    之后其它非法用戶再連接上此端口時(shí),即使不需要LoginMTS(),DataSetProvider和DataSet也已經(jīng)關(guān)聯(lián),非法用戶也就可以訪問應(yīng)用層的DataSet了。  回復(fù)  更多評(píng)論
      


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 野花香高清视频在线观看免费| 中文字幕专区在线亚洲| 免费精品久久天干天干| 亚洲av成本人无码网站| 亚洲欧洲国产经精品香蕉网| 国产亚洲精aa成人网站| 日本久久久免费高清| 一个人免费高清在线观看| 精品无码无人网站免费视频| 伊人免费在线观看| 九一在线完整视频免费观看| 亚洲AV香蕉一区区二区三区| 亚洲国产精品人久久电影| 亚洲另类激情综合偷自拍| 亚洲欧洲日产国码无码网站| 亚洲精品无码专区久久同性男| 热久久精品免费视频| 91情侣在线精品国产免费| 成人免费黄色网址| 亚洲成人免费网址| 99re在线免费视频| 好紧我太爽了视频免费国产| 大妹子影视剧在线观看全集免费| 免费大片av手机看片| 日韩大片免费观看视频播放| 麻豆亚洲AV成人无码久久精品| 国产 亚洲 中文在线 字幕| 亚洲一区二区三区在线| 亚洲videosbestsex日本| 91亚洲自偷手机在线观看| 亚洲成AV人片在WWW色猫咪| 亚洲男同帅GAY片在线观看| 亚洲综合AV在线在线播放| 中文字幕精品亚洲无线码一区应用| 亚洲另类少妇17p| 亚洲一区二区精品视频| 国产亚洲精品成人a v小说| 国产亚洲人成A在线V网站 | 亚洲国产理论片在线播放| 久久精品国产亚洲av麻豆色欲| 91久久亚洲国产成人精品性色 |