我的几乎所有开发经验都在桌面应用程序中.我目前正在使用Delphi 2010,我需要编写一个SOAP客户端来访问California EDD维护的Web服务,以便以电子方式处理工资单数据.我放弃了Delphi WSDL Import
//from StackOverflow Andreas Rejbrand 06/04/2012 procedure WebPostData(const UserAgent: string; const Server: string; const Resource: string; const Data: AnsiString); overload; var hInet: HINTERNET; hHTTP: HINTERNET; hReq: HINTERNET; const accept: packed array[0..1] of LPWSTR = (PChar('*/*'), nil); header: string = 'Content-Type: text/plain'; begin hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); try hHTTP := InternetConnect(hInet, PChar(Server), INTERNET_DEFAULT_HTTP_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 1); try hReq := HttpOpenRequest(hHTTP, PChar('POST'), PChar(Resource), nil, nil, @accept, 0, 1); try if not HttpSendRequest(hReq, PChar(header), length(header), PChar(Data), length(Data)) then raise Exception.Create('HttpOpenRequest failed. ' + SysErrorMessage(GetLastError)); finally InternetCloseHandle(hReq); end; finally InternetCloseHandle(hHTTP); end; finally InternetCloseHandle(hInet); end; end;
我更改了内容类型,因为原始版本似乎永远不会返回.
我这样称呼它:
procedure TForm1.Button1Click(Sender: TObject); var sl: TStringList; s: String; begin sl := TStringList.Create; sl.LoadFromFile('C:\Documents and Settings\Jack\Desktop\My Reading\FSET Development\Ping.xml'); s := sl.Text; sl.Free; WebPostData('BNWebSvc', 'FSETTESTPROD.EDD.CA.GOV','fsetservice', s); end;
在我的浏览器中,主机(FSETTESTPROD.EDD.CA.GOV)存在并响应它可用.当我发布时,我收到404错误可能是因为附加了Web服务名称.在Fiddler2中,输出如下所示:
POST http://FSETTESTPROD.EDD.CA.GOV/fsetservice HTTP/1.1 Accept: */* Content-Type: text/plain User-Agent: BNWebSvc Host: FSETTESTPROD.EDD.CA.GOV Content-Length: 2190 Pragma: no-cache Cookie: __utma=158387685.1851397844.1321382260.1321382260.1321382260.1; __utmz=158387685.1321382260.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=calif%20edd%20eft%20payroll%20processor%20batch%20processing <?xml version="1.0" encoding="utf-8"?> <log> <inputMessage utc="3/2/2007 10:45:44 PM" messageId="urn:uuid:c07c9aef-28db-4843-8dfc-c5b4d3dc363b"> <processingStep description="Unprocessed message"> <soap:Envelope xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>//edd.ca.gov/Ping</wsa:Action> <wsa:MessageID>urn:uuid:c07c9aef-28db-4843-8dfc-c5b4d3dc363b</wsa:MessageID> <wsa:ReplyTo> <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address> </wsa:ReplyTo> <wsa:To>http://localhost:3031/EDD.DMRC.FSET.WebServices/FsetService.asmx</wsa:To> <wsse:Security soap:mustUnderstand="1"> <wsu:Timestamp wsu:Id="Timestamp-0983e8c1-e822-4648-8066-33839f54a6a0"> <wsu:Created>2007-03-02T22:45:41Z</wsu:Created> <wsu:Expires>2007-03-02T22:50:41Z</wsu:Expires> </wsu:Timestamp> <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-0d55d82c-d16d-4c0e-826b-21bf7c805a0f"> <wsse:Username>MyUserName</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MyPassword</wsse:Password> <wsse:Nonce>w6dgDz1DMzKntFsFdEcjhw==</wsse:Nonce> <wsu:Created>2007-03-02T22:45:41Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soap:Header> <soap:Body> <Ping xmlns="http://edd.ca.gov/"> </Ping> </soap:Body> </soap:Envelope> </processingStep> </inputMessage> </log>
我需要在这个工作时使用HTTPS发送它,我可能需要将其合并以使其正常工作.
我正朝着正确的方向前进吗?
Andreas的程序没有说明如何检索响应.如何检索回复?
我想我正在取得一些进展.我将WebPostData更改为一个函数,并从其他地方复制了一些代码以使用SSL并返回结果.它现在看起来像这样:function WebPostData(const UserAgent: string; const Server: string; const Resource: string; const Data: AnsiString): String; var hInet: HINTERNET; hHTTP: HINTERNET; hReq: HINTERNET; BufStream: TMemoryStream; BytesRead: Cardinal; aBuffer : Array[0..4096] of Char; flags : DWord; const accept: packed array[0..1] of LPWSTR = (PChar('*/*'), nil); header: string = 'Content-Type: text/plain'; begin hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); try hHTTP := InternetConnect(hInet, PChar(Server), INTERNET_DEFAULT_HTTPS_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 1); try flags := INTERNET_FLAG_SECURE or INTERNET_FLAG_KEEP_CONNECTION; hReq := HttpOpenRequest(hHTTP, PChar('POST'), PChar(Resource), nil, nil, @accept, flags, 1); try if not HttpSendRequest(hReq, PChar(header), length(header), PChar(Data), length(Data)) then begin raise Exception.Create('HttpOpenRequest failed. ' + SysErrorMessage(GetLastError)); end else begin BufStream := TMemoryStream.Create; try while InternetReadFile(hReq, @aBuffer, SizeOf(aBuffer), BytesRead) do begin if (BytesRead = 0) then Break; BufStream.Write(aBuffer, BytesRead); end; aBuffer[0] := #0; BufStream.Write(aBuffer, 1); Result := PChar(BufStream.Memory); finally BufStream.Free; end; end; finally InternetCloseHandle(hReq); end; finally InternetCloseHandle(hHTTP); end; finally InternetCloseHandle(hInet); end; end;
我现在在Fiddler得到两个结果,一个成功,一个没有.
成功的一个:
CONNECT fsettestprod.edd.ca.gov:443 HTTP/1.0 User-Agent: BNWebSvc Host: FSETTESTPROD.EDD.CA.GOV:443 Content-Length: 0 Connection: Keep-Alive Pragma: no-cache A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below. Major Version: 3 Minor Version: 1 Random: 4F 28 1F 92 96 EA 2C 64 91 59 12 84 D1 F3 F8 ED BA 89 A5 44 94 D6 50 E0 CF 9B FA 12 5F 57 AD EB SessionID: empty Ciphers: [0004] SSL_RSA_WITH_RC4_128_MD5 [0005] SSL_RSA_WITH_RC4_128_SHA [000A] SSL_RSA_WITH_3DES_EDE_SHA [0009] SSL_RSA_WITH_DES_SHA [0064] TLS_RSA_EXPORT1024_WITH_RC4_56_SHA [0062] TLS_RSA_EXPORT1024_WITH_DES_SHA [0003] SSL_RSA_EXPORT_WITH_RC4_40_MD5 [0006] SSL_RSA_EXPORT_WITH_RC2_40_MD5 [0013] SSL_DHE_DSS_WITH_3DES_EDE_SHA [0012] SSL_DHE_DSS_WITH_DES_SHA [0063] TLS_DHE_DSS_EXPORT1024_WITH_DES_SHA
而不成功的一个:
POST https://FSETTESTPROD.EDD.CA.GOV/fsetservice HTTP/1.1 Accept: */* Content-Type: text/plain User-Agent: BNWebSvc Host: FSETTESTPROD.EDD.CA.GOV Content-Length: 2190 Connection: Keep-Alive Cache-Control: no-cache Cookie: __utma=158387685.1851397844.1321382260.1321382260.1321382260.1; __utmz=158387685.1321382260.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=calif%20edd%20eft%20payroll%20processor%20batch%20processing <?xml version="1.0" encoding="utf-8"?> <log> <inputMessage utc="3/2/2007 10:45:44 PM" messageId="urn:uuid:c07c9aef-28db-4843-8dfc-c5b4d3dc363b"> <processingStep description="Unprocessed message"> <soap:Envelope xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soap:Header> <wsa:Action>//edd.ca.gov/Ping</wsa:Action> <wsa:MessageID>urn:uuid:c07c9aef-28db-4843-8dfc-c5b4d3dc363b</wsa:MessageID> <wsa:ReplyTo> <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address> </wsa:ReplyTo> <wsa:To>http://localhost:3031/EDD.DMRC.FSET.WebServices/FsetService.asmx</wsa:To> <wsse:Security soap:mustUnderstand="1"> <wsu:Timestamp wsu:Id="Timestamp-0983e8c1-e822-4648-8066-33839f54a6a0"> <wsu:Created>2007-03-02T22:45:41Z</wsu:Created> <wsu:Expires>2007-03-02T22:50:41Z</wsu:Expires> </wsu:Timestamp> <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-0d55d82c-d16d-4c0e-826b-21bf7c805a0f"> <wsse:Username>***MyUserName***</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">***MyPassword***</wsse:Password> <wsse:Nonce>w6dgDz1DMzKntFsFdEcjhw==</wsse:Nonce> <wsu:Created>2007-03-02T22:45:41Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soap:Header> <soap:Body> <Ping xmlns="http://edd.ca.gov/"> </Ping> </soap:Body> </soap:Envelope> </processingStep> </inputMessage> </log>
我介绍了我的代码并观察了Fiddler的反应.当我跨过HTTPSendRequest行时,两条消息都出现了.在我的按钮单击事件中,我将函数的结果分配给备忘录控件,但我得到的是一堆表示不可打印字符的正方形.
我得到的结果是否表明流程良好但内容不好?
这仍然是一个问题,因为你无法以这种方式访问WebService?
我如何解密结果或者当我得到正确的流程时会自动发生这种情况?