最近的做的项目需要用到对方提供的WebService,是用java做的,带证书的(即必须使用https访问的),现在怎么也掉不成功。刚开始报一个“XML 文件必须有一个顶层元素”的错误,现在是什么都没改,调了以后很长时间没反应,最后报一个“要操作的句柄的状态错误”,后面是个URL。各位网友有遇到这样的问题的吗?如果有,请提供个方法,定不胜感激!
另外,如果能通过什么方法可以检测到我发出去的请求信息及对方返回的信息吗?最好是能在Delphi里看到明文的。因为用wireshark,tcptrace之类的检测工具看到的是加密后的,不能用。
另外,如果能通过什么方法可以检测到我发出去的请求信息及对方返回的信息吗?最好是能在Delphi里看到明文的。因为用wireshark,tcptrace之类的检测工具看到的是加密后的,不能用。
我正好刚做完这样的项目
我把一些相关东西放在了我的笔记本上了
http://www.wanggq.cn/post/23.html包括需要的一些文件在附件里直接下载就行了
另外,如果那位朋友知道怎么用idhttp调用webservice的话,也给个办法吧!小弟不胜感激!
你直接通过tidhttp控件调用webservice的接口地址就可以了啊,接口地址也就是一串http或者https开头的地址啊,在我的笔记本的上一篇笔记中有说明,还给出了部分代码,你再去看一下就知道了,当然具体是用post,put还是get方法要看你实际需要了调用http和调用https的方法是一样的,只是https多个加密验证的控件而已
get是从服务器端取数据时用的,一般返回xml串
put是从客户端上传文件到服务器时用的,你要把数据封装成webservice指定的xml格式,然后上传
post用的比较少,一般是要更新服务器端的数据时用的具体有哪些接口,用到几个什么参数,你一定要跟开发webservice的人沟通好
get是从服务器端取数据时用的,一般返回xml串
put是从客户端上传文件到服务器时用的,你要把数据封装成webservice指定的xml格式,然后上传
post用的比较少,一般是要更新服务器端的数据时用的具体有哪些接口,用到几个什么参数,你一定要跟开发webservice的人沟通好
XML 文件必须有一个顶层元素(在另一台电脑上调试是:XML document must have a top level element )真的好郁闷啊,这个问题是出现在哪里的啊?是服务器的错误信息还是这边解析的错误信息,是发送的时候还是接收的时候啊?
你需要的话可以另外开个帖子问一下最简单的方法就是你可以把返回的信息直接打出来,看一下就知道是服务端返回错误还是你解析的问题,因为返回的xml也是一串字符串,你可以直接把xml字符串发给开发webservice的人员看一下,是不是正确的另外一种简单的方法的就是把你调用接口的地址(好像只能是get方法)直接在ie浏览器中输入,如果调用正确的话ie中就会直接显示xml文件档的内容
你随便定义一个字符串接收就行了啊
var
str:string;
begin
str:=Idhttp.get('https://.....');
//这里str就是返回的xml字符串
end;
wsdl是用soap协议的,我刚才说的都是基于http协议的
如果是用soap的协议的不能用Tidhttp控件,要用soap控件
delphi自带的控件就有
那你有办法解决吗?关键是不能指定其XML文件格式为UTF-8,设置了也无效,有朋友遇见过这种情况吗?
指定xml文件为utf-8很简单
用encodeutf8这个函数就可以了,delphi自带的函数
// 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.
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.
可是我遇见的问题是这样的,比如执行到上面的调用接口那一步
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"?>
好了,结贴放分!