• delphi用webservice


     delphi的webservice开发。

    一、在已有的项目中,调用外部的webservice

    1、根据向导建webservice,在项目中引入“WSDL Importer"。假设引入后生成的类的名字为”service"

        

    2、对生成的service类做相应的修改。

        2.1、如果webservice方法里的某些参数即是接收传入参数又是接收返回参数,在delphi里要对参数名字重新命名

    如在用c#写的webservice的服务端方法是sr.Get_Delivery_Data_Over(sn, sjlx, ref err);
    //默认生成的代码为   
     procedure Get_Delivery_Data(const err: WideString; const data_str: TByteDynArray; const sn: Integer; const sjlx: WideString; out Get_Delivery_DataResult: Boolean; out err: WideString; out data_str: TByteDynArray; out sn: Integer); stdcall;
    ///要改成如下:
     procedure Get_Delivery_Data(const err1: WideString; const data_str1: TByteDynArray; const sn1: Integer; const sjlx: WideString; out Get_Delivery_DataResult: Boolean; out err: WideString; out data_str: TByteDynArray; out sn: Integer); stdcall;

       2.2、 如果delphi调用c#写的webservice时,服务器端方法接收到delphi传过来的参数总是为空时,在delphi的service类的initialization下面加这名话

     InvRegistry.RegisterInvokeOptions(TypeInfo(ServiceSoap),ioDocument);   ///必需要加,不然传到c#写的webservice里的方法的参数值是空的

      如下是service类的源代码

    // ************************************************************************ //
    // The types declared in this file were generated from data read from the
    // WSDL File described below:
    // WSDL     : http://fti.yndzyf.com/Service.asmx?wsdl
    // Encoding : utf-8
    // Version  : 1.0
    // (2014-05-21 16:32:33 - 1.33.2.5)
    // ************************************************************************ //
    
    unit Service;
    
    interface
    
    uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;
    
    type
    
      // ************************************************************************ //
      // The following types, referred to in the WSDL document are not being represented
      // in this file. They are either aliases[@] of other types represented or were referred
      // to but never[!] declared in the document. The types from the latter category
      // typically map to predefined/known XML or Borland types; however, they could also 
      // indicate incorrect WSDL documents that failed to declare or import a schema type.
      // ************************************************************************ //
      // !:string          - "http://www.w3.org/2001/XMLSchema"
      // !:base64Binary    - "http://www.w3.org/2001/XMLSchema"
      // !:int             - "http://www.w3.org/2001/XMLSchema"
      // !:boolean         - "http://www.w3.org/2001/XMLSchema"
    
      Websoap              = class;                 { "http://aitf.yndzyf.com/"[H] }
    
    
    
      // ************************************************************************ //
      // Namespace : http://aitf.yndzyf.com/
      // ************************************************************************ //
      Websoap = class(TSOAPHeader)
      private
        FUserName: WideString;
        FPassWord: WideString;
      published
        property UserName: WideString read FUserName write FUserName;
        property PassWord: WideString read FPassWord write FPassWord;
      end;
    
    
      // ************************************************************************ //
      // Namespace : http://aitf.yndzyf.com/
      // soapAction: http://aitf.yndzyf.com/%operationName%
      // transport : http://schemas.xmlsoap.org/soap/http
      // binding   : ServiceSoap
      // service   : Service
      // port      : ServiceSoap
      // URL       : http://fti.yndzyf.com/Service.asmx
      // ************************************************************************ //
      ServiceSoap = interface(IInvokable)
      ['{E00EB65B-7136-E473-42EF-D3135F25019F}']
        procedure Get_Delivery_Data(const err1: WideString; const data_str1: TByteDynArray; const sn1: Integer; const sjlx: WideString; out Get_Delivery_DataResult: Boolean; out err: WideString; out data_str: TByteDynArray; out sn: Integer); stdcall;
        procedure Get_Delivery_Data_Over(const sn: Integer; const sjlx: WideString; const err1: WideString; out Get_Delivery_Data_OverResult: Boolean; out err: WideString); stdcall;
        procedure Receive_data(const error1: WideString; const str: TByteDynArray; const sn: Integer; const sjlx: WideString; out Receive_dataResult: Boolean; out error: WideString); stdcall;
      end;
    
    function GetServiceSoap(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil;user:string='';password:string=''): ServiceSoap;
    
    
    implementation
    
    function GetServiceSoap(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO;user:string;password:string): ServiceSoap;
    const
      defWSDL = 'http://fti.yndzyf.com/Service.asmx?wsdl';
      defURL  = 'http://fti.yndzyf.com/Service.asmx';
      defSvc  = 'Service';
      defPrt  = 'ServiceSoap';
    var
      RIO: THTTPRIO;
    begin
      Result := nil;
      if (Addr = '') then
      begin
        if UseWSDL then
          Addr := defWSDL
        else
          Addr := defURL;
      end;
      if HTTPRIO = nil then
        RIO := THTTPRIO.Create(nil)
      else
        RIO := HTTPRIO;
      try
        Result := (RIO as ServiceSoap);
        if UseWSDL then
        begin
          RIO.WSDLLocation := Addr;
          RIO.Service := defSvc;
          RIO.Port := defPrt;
        end else
          RIO.URL := Addr;
      finally
        if (Result = nil) and (HTTPRIO = nil) then
          RIO.Free;
      end;
    end;
    
    
    initialization
      InvRegistry.RegisterInterface(TypeInfo(ServiceSoap), 'http://aitf.yndzyf.com/', 'utf-8');
      InvRegistry.RegisterDefaultSOAPAction(TypeInfo(ServiceSoap), 'http://aitf.yndzyf.com/%operationName%');
      InvRegistry.RegisterHeaderClass(TypeInfo(ServiceSoap), Websoap, 'Websoap', '');
      RemClassRegistry.RegisterXSClass(Websoap, 'http://aitf.yndzyf.com/', 'Websoap');
      InvRegistry.RegisterInvokeOptions(TypeInfo(ServiceSoap),ioDocument);   ///必要要加,不然传到c#写的webservice里的值是空的
    end.

     3、调用

    procedure Tform_smrk.bgetydClick(Sender: TObject);
    var sql:string;
    var err_fp,err1_fp,err_yjm,err1_yjm:Widestring;
    data_fp,data_fp1,data_yjm,data_yjm1:TByteDynArray;
    sn_fp,sn_fp1,sn_yjm,sn_yjm1:Integer;
    flag_fp,flag_fp1,flag_yjm,flag_yjm1:boolean;
    ws:webSoap;
    svc:serviceSoap;
    begin
           svc := HTTPRIO1 as ServiceSoap;
           ws:=websoap.Create;
           ws.UserName:=serviceName;///webservice的用户名和密码
           ws.PassWord:=servicePassword;
          (svc as ISOAPHeaders).Send(ws);
           svc.Get_Delivery_Data('',data_fp1,0,'运单',flag_fp,err_fp,data_fp,sn_fp);
           (svc as ISOAPHeaders).Send(ws);///每次调用时都要重新设置用户和密码
           svc.Get_Delivery_Data('',data_yjm1,0,'电子监管',flag_yjm,err_yjm,data_yjm,sn_yjm);
           if length(data_fp)>0 then///如果有运单
           begin
              ADOStoredProc1.ProcedureName:= 'p_insert_data';
              ADOStoredProc1.Parameters.Clear;
              ADOStoredProc1.Parameters.Refresh;
              ADOStoredProc1.Parameters.ParamByName('@data_str').Value:=data_fp;
              if length(data_yjm)>0  then  ADOStoredProc1.Parameters.ParamByName('@data_str_yjm').Value:=data_yjm;
              ADOStoredProc1.Prepared;
              ADOStoredProc1.ExecProc;    
    end

       要注意的是:1、每次调用webservice时要重新写一次(svc as ISOAPHeaders).Send(ws);,将webSoap和serviceSoap关联

                        2、上面的代码是从webservice取xml的二进制文件,然后将取出的二进制数据传入到存储过程p_insert_data里。用ADOStoreProc可以对存储过程传参数

                             时可以不考虑参数的类型,直接用ADOStoredProc1.Parameters.ParamByName('@data_str').Value:=data_fp赋值,在赋值前要ADOStoredProc1.Parameters.Refresh;不然不能对参数                          赋值成功。

                        3、HTTPRIO1 是控件THTTPRIO。控件要设置好URL=http://fti.yndzyf.com/Service.asmx?wsdl

  • 相关阅读:
    Expert C programming书摘
    修改文件时间属性的方法
    算法学习, 开始计划
    小游戏学习搜集
    C++ 练习记录2---Effective STL中的vector<bool>
    C++ 练习记录1--vector<T> 中T的初始化
    oracle的wm_concat函数实现行转列
    Oracle批量插入有日期类型数据
    如何将zTree选中节点传递给后台
    第五章:1.数组和广义表 -- 数组
  • 原文地址:https://www.cnblogs.com/shengyu-kmust/p/4047866.html
Copyright © 2020-2023  润新知