Форум: "Начинающим";
Текущий архив: 2011.12.18;
Скачать: [xml.tar.bz2];
ВнизОтправка Soap Headers Найти похожие ветки
← →
Servy © (2011-09-05 13:10) [0]Возникла необходимость написать клиент к одному 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/RADStudio/en/Defining_and_Using_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, и тем более особенностей ее реализации в Делфи далеки до идеала.
← →
Servy © (2011-09-07 01:07) [1]На случай, если кто-то найдет этот тред поиском, поделюсь воплощенным решением:
После копания генофонда, выяснилось, что добавлять чужие xmlns в SOAP:Envelope делфи не умеет в принципе, кроме того, нормального способа дописать их туда, не меняя пресловутый генофонд, или не используя ужас вроде StringReplace"а получившегося xml"я, не нашлось. Судя по всему, по спецификации SOAP"а, которую я полностью естесственно не осилил, эти самые xmlns можно писать и по месту, так, как это делает Делфи, то есть например так:
<SOAP-ENV:Envelope ...>
<SOAP-ENV:Body>
<redeemVoucher xmlns="http://serviceurl">
вмето
<SOAP-ENV:Envelope xmlns:ns1="http://serviceurl/" ...>
<SOAP-ENV:Body>
<ns1:redeemVoucher>
Соответственно, проблема была преобразована в другую: получить от Делфи заголовок вида:
<SOAP-ENV:Header>
<Authorization xmlns="redeemVoucher">Basic b2N0b2JlcjoxMjM0</Authorization>
</SOAP-ENV:Header>
Так как с помощью опций и другого мелкого вмешательства этого добиться не удалось, пришлось вмешаться в процесс преобразования объект->xml, и написать свой класс заголовка такого вида:
TAuthHeader = class(TSOAPHeader)
private
FAuthorization: string;
published
property Authorization: string read FAuthorization write FAuthorization;
public
function ObjectToSOAP(RootNode, ParentNode: IXMLNode;
const ObjConverter: IObjConverter;
const NodeName, NodeNamespace, ChildNamespace: InvString; ObjConvOpts: TObjectConvertOptions;
out RefID: InvString): IXMLNode; override;
end;
type
TSOAPDomConvAccess = class(TSOAPDomConv);
function TAuthHeader.ObjectToSOAP(RootNode, ParentNode: IXMLNode;
const ObjConverter: IObjConverter; const NodeName, NodeNamespace,
ChildNamespace: InvString; ObjConvOpts: TObjectConvertOptions;
out RefID: InvString): IXMLNode;
var
Conv: TSOAPDomConv;
begin
Result := ParentNode.AddChild("Authorization", "redeemVoucher", False);
Conv := (ObjConverter as TSOAPDomConv);
RefId := TSOAPDomConvAccess(Conv).GetNewID;
Result.Text := FAuthorization;
end;
В результате добавления заголовка такого класса, генерируется требуемый xml, без двойного тега в SOAP-header и с нужным неймспейсом, и сервис на другом конце это дело успешно ест.
← →
Плохиш © (2011-09-07 11:32) [2]Стоит разместить это на http://edn.embarcadero.com/
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2011.12.18;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.004 c