最近的做的项目需要用到对方提供的WebService,是用java做的,带证书的(即必须使用https访问的),现在怎么也掉不成功。刚开始报一个“XML 文件必须有一个顶层元素”的错误,现在是什么都没改,调了以后很长时间没反应,最后报一个“要操作的句柄的状态错误”,后面是个URL。各位网友有遇到这样的问题的吗?如果有,请提供个方法,定不胜感激!
另外,如果能通过什么方法可以检测到我发出去的请求信息及对方返回的信息吗?最好是能在Delphi里看到明文的。因为用wireshark,tcptrace之类的检测工具看到的是加密后的,不能用。

解决方案 »

  1.   

    算你运气好
    我正好刚做完这样的项目
    我把一些相关东西放在了我的笔记本上了
    http://www.wanggq.cn/post/23.html包括需要的一些文件在附件里直接下载就行了
      

  2.   

    呵呵,兄弟,可是怎么用TIdHTTP调用webservice呢?
      

  3.   

    已经查看到发送之前的xml了,发现开头是这样的<?xml version="1.0" ?> 没有 encoding="UTF-8" 这一句,可是我已经设置了HTTPWebNode.UseUTF8InHeader := true 了啊,为什么还是encoding="UTF-8"这句呢?
    另外,如果那位朋友知道怎么用idhttp调用webservice的话,也给个办法吧!小弟不胜感激!
      

  4.   


    你直接通过tidhttp控件调用webservice的接口地址就可以了啊,接口地址也就是一串http或者https开头的地址啊,在我的笔记本的上一篇笔记中有说明,还给出了部分代码,你再去看一下就知道了,当然具体是用post,put还是get方法要看你实际需要了调用http和调用https的方法是一样的,只是https多个加密验证的控件而已
      

  5.   

    是不是必须webservice提供了get和post的方法才能调用呢?可现在不知道对方提供了没有?今天他们不上班。现在我直接调用Webservice的接口地址,报错。内容如下:“HTTP/1.1 405 Method Not Allowed”是不是不能调用这个方法呢?
      

  6.   

    是啊,返回的错误说明都说了方法不支持,不般都是用post,put,get这3个方法
    get是从服务器端取数据时用的,一般返回xml串
    put是从客户端上传文件到服务器时用的,你要把数据封装成webservice指定的xml格式,然后上传
    post用的比较少,一般是要更新服务器端的数据时用的具体有哪些接口,用到几个什么参数,你一定要跟开发webservice的人沟通好
      

  7.   

    是啊,返回的错误说明都说了方法不支持,一般都是用post,put,get这3个方法
    get是从服务器端取数据时用的,一般返回xml串
    put是从客户端上传文件到服务器时用的,你要把数据封装成webservice指定的xml格式,然后上传
    post用的比较少,一般是要更新服务器端的数据时用的具体有哪些接口,用到几个什么参数,你一定要跟开发webservice的人沟通好
      

  8.   

    调用对应的方法的时候就出这个问题
    XML 文件必须有一个顶层元素(在另一台电脑上调试是:XML document must have a top level element )真的好郁闷啊,这个问题是出现在哪里的啊?是服务器的错误信息还是这边解析的错误信息,是发送的时候还是接收的时候啊?
      

  9.   

    这个问题不属于本帖的讨论范围了
    你需要的话可以另外开个帖子问一下最简单的方法就是你可以把返回的信息直接打出来,看一下就知道是服务端返回错误还是你解析的问题,因为返回的xml也是一串字符串,你可以直接把xml字符串发给开发webservice的人员看一下,是不是正确的另外一种简单的方法的就是把你调用接口的地址(好像只能是get方法)直接在ie浏览器中输入,如果调用正确的话ie中就会直接显示xml文件档的内容
      

  10.   

    。。
    你随便定义一个字符串接收就行了啊
    var
      str:string;
    begin
      str:=Idhttp.get('https://.....');
      //这里str就是返回的xml字符串
    end;
      

  11.   

    他提供的接口地址是个WSDL文档,直接调用Webservice的接口地址,报错。内容如下:“HTTP/1.1 405 Method Not Allowed”,不会返回任何信息
      

  12.   

    晕,不早点说
    wsdl是用soap协议的,我刚才说的都是基于http协议的
    如果是用soap的协议的不能用Tidhttp控件,要用soap控件
    delphi自带的控件就有
      

  13.   

    呵呵,昨天我也郁闷呢!我说怎么对不上啊
    那你有办法解决吗?关键是不能指定其XML文件格式为UTF-8,设置了也无效,有朋友遇见过这种情况吗?
      

  14.   


    指定xml文件为utf-8很简单
    用encodeutf8这个函数就可以了,delphi自带的函数
      

  15.   

    不是这个意思,是delphi自生成XML 文件头的没有,它生成是这个样子的:<?xml version="1.0" ?> ,但我需要的是这个样子的:<?xml version="1.0" encoding="UTF-8"?>网上都说设置HTTPWebNode.UseUTF8InHeader := true 就可以了,但我设置了,无效!是不是还有其他要注意的,我用的是delphi2010
      

  16.   

    service:// ************************************************************************ //
    // The types declared in this file were generated from data read from the
    // WSDL File described below:
    // WSDL     : http://172.20.100.10/test/service.asmx?wsdl
    //  >Import : http://172.20.100.10/test/service.asmx?wsdl:0
    // Encoding : utf-8
    // Version  : 1.0
    // (2010/6/22 上午 11:31:35 - - $Rev: 10138 $)
    // ************************************************************************ //unit service;interfaceuses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;const
      IS_OPTN = $0001;
      IS_REF  = $0080;
    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"[Gbl]  // ************************************************************************ //
      // Namespace : Kye
      // soapAction: Kye/HelloWorld
      // transport : http://schemas.xmlsoap.org/soap/http
      // style     : document
      // binding   : ServiceSoap
      // service   : Service
      // port      : ServiceSoap
      // URL       : http://172.20.100.10/test/service.asmx
      // ************************************************************************ //
      ServiceSoap = interface(IInvokable)
      ['{B82FAFBA-EAB8-AD5C-2535-FB6046355616}']
        function  HelloWorld(const name_: WideString): WideString; stdcall;
      end;function GetServiceSoap(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): ServiceSoap;
    implementation
      uses SysUtils;function GetServiceSoap(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): ServiceSoap;
    const
      defWSDL = 'http://172.20.100.10/test/service.asmx?wsdl';
      defURL  = 'http://172.20.100.10/test/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), 'Kye', 'utf-8');
      InvRegistry.RegisterDefaultSOAPAction(TypeInfo(ServiceSoap), 'Kye/HelloWorld');
      InvRegistry.RegisterInvokeOptions(TypeInfo(ServiceSoap), ioDocument);
      InvRegistry.RegisterExternalParamName(TypeInfo(ServiceSoap), 'HelloWorld', 'name_', 'name');end.
      

  17.   

    調用:unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,service, StdCtrls;type
      TForm1 = class(TForm)
        btn1: TButton;
        edt1: TEdit;
        Label1: TLabel;
        procedure btn1Click(Sender: TObject);
      private
        aa:ServiceSoap;
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
    begin
      aa:=GetServiceSoap(False,'',nil);
      ShowMessage(aa.HelloWorld(edt1.Text));
    end;end.
     
      

  18.   

    呵呵,谢谢楼上这位兄弟,可是要是有这么简单就好了!
    可是我遇见的问题是这样的,比如执行到上面的调用接口那一步
     aa:=GetServiceSoap(False,'',nil);
    它就停在这里了,等了一会儿,跳出一个“XML 文件必须有一个顶层元素”的错误!
    后来我在窗体上放了个控件THTTPRIO,在他的BeforeExecute事件里,写了段代码对发送出去的XML进行跟踪
    procedure TForm1.HTTPRIO1BeforeExecute(const MethodName: string;
      SOAPRequest: TStream);
    var
      filStrm:TMemoryStream;
      StrStrm:TStringStream;
    begin
      Memo2.Text:=MethodName;  StrStrm:=TStringStream.Create;
      StrStrm.CopyFrom(SOAPRequest,0);
      TMemoryStream(SOAPRequest).LoadFromFile('d:\aa.xml');
      Memo2.Text:=StrStrm.DataString;
      Self.Update;
    end;显示出的代码是这样的:
    <?xml version="1.0"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><nciicGetCondition xmlns="https://api.nciic.org.cn/NciicServices"><parameters><inLicense>.....</inLicense></parameters></nciicGetCondition></SOAP-ENV:Body></SOAP-ENV:Envelope>如果他能在xml文件头里加上 encoding="UTF-8" 就对了,可是我使出所有方法,在网上寻觅千百度也没有找到方法,也就是说如果结果是这样就行了<?xml version="1.0"  encoding="UTF-8"?>
      

  19.   

    问下对方能用post、get方法吗?能用的话好很多。
      

  20.   

    各位朋友好!我是来报喜的!这个问题终于解决了,原来是对方给的接口地址问题,前几天给的是https开头的,一直调不成功,今天给了个http开头的,一下就成功了,呵呵,那个爽啊!
    好了,结贴放分!