|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Отправка Soap Headers
Возникла необходимость написать клиент к одному SOAP-сервису. От авторов сервиса пришел пример, как должен выглядеть запрос, он приведен ниже. Я заменил url сервиса заказчика на "http://serviceurl/", ибо он длинный и не должен быть доступен широкой публике:
Код:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://serviceurl/" xmlns:ns2="redeemVoucher"> <SOAP-ENV:Header> <ns2:Authorization>Basic b2N0b2JlcjoxMjM0</ns2:Authorization> </SOAP-ENV:Header> <SOAP-ENV:Body> <ns1:redeemVoucher> <partner_id>26538</partner_id> <voucher_id>9910000000980</voucher_id> <timeout>20</timeout> <transaction_data>Some data here </transaction_data> </ns1:redeemVoucher> </SOAP-ENV:Body> </SOAP-ENV:Envelope> В Делфи я экспортнул wsdl'ку. Header в wsdl'ке не описан. Прочитав: http://docwiki.embarcadero.com/RADSt...g_SOAP_Headers Я написал следующий код: Код:
TAuthHeader = class(TSOAPHeader) private FAuthorization: string; published property Authorization: string read FAuthorization write FAuthorization; end; // ... initialization { VoucherService } InvRegistry.RegisterInterface(TypeInfo(VoucherService), 'http://serviceurl/', 'UTF-8'); // сгенерировано делфи InvRegistry.RegisterHeaderClass(TypeInfo(VoucherService), TAuthHeader, 'Authentification', ''); RemClassRegistry.RegisterSerializeOptions(TAuthHeader, [xoSimpleTypeWrapper]); При вызове передаю заголовок следующим образом: Код:
function SendRedeemVoucherW(PartnerId: PWideChar; VoucherId: PWideChar; Timeout: Integer; TransactionData: PWideChar): HRESULT; var Headers: ISOAPHeaders; H: TAuthHeader; begin LogWrite('redeemVoucher has been called', Standart); Headers := PartnerVoucherService as ISOAPHeaders; H := TAuthHeader.Create; H.Authorization := 'Basic b2N0b2JlcjoxMjM0'; Headers.OwnsSentHeaders := True; Headers.Send(H); Result := PartnerVoucherService.redeemVoucher(PartnerId, VoucherId, Timeout, TransactionData); При этом, Делфи отправляет следующий запрос (я отформатировал xml, чтобы удобнее было читать): Код:
POST / HTTP/1.1 SOAPAction: "" Content-Type: text/xml; charset="utf-8" User-Agent: CodeGear SOAP 1.3 Host: localhost:8333 Content-Length: 652 Connection: Keep-Alive Cache-Control: no-cache <?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:Header> <NS1:TAuthHeader xmlns:NS1="urn:uVoucher"> <NS1:Authorization>Basic b2N0b2JlcjoxMjM0</NS1:Authorization> </NS1:TAuthHeader> </SOAP-ENV:Header> <SOAP-ENV:Body> <redeemVoucher xmlns="http://services.partnergw.servop.ru/"> <partner_id xmlns="">26538</partner_id> <voucher_id xmlns="">9910000000980</voucher_id> <timeout xmlns="">10</timeout> <transaction_data xmlns="">Some data</transaction_data> </redeemVoucher> </SOAP-ENV:Body> </SOAP-ENV:Envelope> Сервис возвращает ошибку авторизации. Собственно вопрос - как передать soap-header так, как этого ждет сервис: Код:
<SOAP-ENV:Header> <ns2:Authorization>Basic b2N0b2JlcjoxMjM0</ns2:Authorization> </SOAP-ENV:Header> А не так, как это происходит при использовании вышеприведенного кода, написанного (ну, я старался ^_^) согласно справке: Код:
<SOAP-ENV:Header> <NS1:TAuthHeader xmlns:NS1="urn:uVoucher"> <NS1:Authorization>Basic b2N0b2JlcjoxMjM0</NS1:Authorization> </NS1:TAuthHeader> </SOAP-ENV:Header> Есть злобный вариант - просто открыть сокет и писать туда все руками так, как этого ждет сервис. Но формирование SOAP запроса руками видится мне костылем, и убивает всю "идею" соапа. Полезные ссылки по теме тоже приветствуются. P.S. Мои знания технологии SOAP, и тем более особенностей ее реализации в Делфи далеки до идеала. |