2016-03-05 6 views
3

Привет, я загружаю java webservice в Delphi 7 через WSDL. Когда я вызываю веб-службу из delphi, я становлюсь ниже ошибки. Я здесь, без всякой подсказки.Ошибка Unmarshalling: cvc-complex-type.2.4.a: Недействительный контент был найден, начиная с элемента 'XXXXX'. Ожидается один из «{XXXXX}»

'Unmarshalling Error: cvc-complex-type.2.4.a: Invalid content was found starting with element 'XXXXX'. One of '{XXXXX}' is expected

Использование WSDL Дельфи генерации кода ниже. Я удалил много методов в код ниже.

// ************************************************************************ // 
// The types declared in this file were generated from data read from the 
// WSDL File described below: 
// WSDL  : http://localhost/protectappws/services/ProtectappwsImpl?wsdl 
// Encoding : UTF-8 
// Version : 1.0 
// (3/5/2016 5:55:17 AM - 1.33.2.5) 
// ************************************************************************ // 

unit ProtectappwsImpl; 

interface 

uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns; 

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" 
    // !:boolean   - "http://www.w3.org/2001/XMLSchema" 
    // !:int    - "http://www.w3.org/2001/XMLSchema" 

    Encrypt    = class;     { "http://dsws.org/protectappws/" } 
    Decrypt    = class;     { "http://dsws.org/protectappws/" } 


    // ************************************************************************ // 
    // Namespace : http://dsws.org/protectappws/ 
    // Serializtn: [xoLiteralParam] 
    // ************************************************************************ // 
    Encrypt = class(TRemotable) 
    private 
    Fusername: WideString; 
    Fpassword: WideString; 
    Fkeyname: WideString; 
    Fkeyiv: WideString; 
    Ftransformation: WideString; 
    Fplaintext: WideString; 
    public 
    constructor Create; override; 
    published 
    property username: WideString read Fusername write Fusername; 
    property password: WideString read Fpassword write Fpassword; 
    property keyname: WideString read Fkeyname write Fkeyname; 
    property keyiv: WideString read Fkeyiv write Fkeyiv; 
    property transformation: WideString read Ftransformation write Ftransformation; 
    property plaintext: WideString read Fplaintext write Fplaintext; 
    end; 

    EncryptResponse = type WideString;  { "http://dsws.org/protectappws/"[L] } 


    // ************************************************************************ // 
    // Namespace : http://dsws.org/protectappws/ 
    // Serializtn: [xoLiteralParam] 
    // ************************************************************************ // 
    Decrypt = class(TRemotable) 
    private 
    Fusername: WideString; 
    Fpassword: WideString; 
    Fkeyname: WideString; 
    Fkeyiv: WideString; 
    Ftransformation: WideString; 
    Fciphertext: WideString; 
    public 
    constructor Create; override; 
    published 
    property username: WideString read Fusername write Fusername; 
    property password: WideString read Fpassword write Fpassword; 
    property keyname: WideString read Fkeyname write Fkeyname; 
    property keyiv: WideString read Fkeyiv write Fkeyiv; 
    property transformation: WideString read Ftransformation write Ftransformation; 
    property ciphertext: WideString read Fciphertext write Fciphertext; 
    end; 

    DecryptResponse = type WideString;  { "http://dsws.org/protectappws/"[L] } 


    // ************************************************************************ // 
    // Namespace : http://dsws.org/protectappws/ 
    // soapAction: http://dsws.org/protectappws/%operationName% 
    // transport : http://schemas.xmlsoap.org/soap/http 
    // style  : document 
    // binding : protectappwsSOAP 
    // service : protectappws 
    // port  : protectappwsSOAP 
    // URL  : http://localhost/protectappws/services/ProtectappwsImpl 
    // ************************************************************************ // 
    protectappws = interface(IInvokable) 
    ['{EAB73212-14C4-1A41-ABFA-F106C8EB9965}'] 
    function Encrypt(const parameters: Encrypt): EncryptResponse; stdcall; 
    function Decrypt(const parameters: Decrypt): DecryptResponse; stdcall; 
    end; 

function Getprotectappws(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): protectappws; 


implementation 

function Getprotectappws(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): protectappws; 
const 
    defWSDL = 'http://localhost/protectappws/services/ProtectappwsImpl?wsdl'; 
    defURL = 'http://localhost/protectappws/services/ProtectappwsImpl'; 
    defSvc = 'protectappws'; 
    defPrt = 'protectappwsSOAP'; 
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 protectappws); 
    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; 




constructor Encrypt.Create; 
begin 
    inherited Create; 
    FSerializationOptions := [xoLiteralParam]; 
end; 

constructor Decrypt.Create; 
begin 
    inherited Create; 
    FSerializationOptions := [xoLiteralParam]; 
end; 

initialization 
    InvRegistry.RegisterInterface(TypeInfo(protectappws), 'http://dsws.org/protectappws/', 'UTF-8'); 
    InvRegistry.RegisterDefaultSOAPAction(TypeInfo(protectappws), 'http://dsws.org/protectappws/%operationName%'); 
    InvRegistry.RegisterInvokeOptions(TypeInfo(protectappws), ioDocument); 
    InvRegistry.RegisterInvokeOptions(TypeInfo(protectappws), ioLiteral); 
    RemClassRegistry.RegisterXSInfo(TypeInfo(EncryptResponse), 'http://dsws.org/protectappws/', 'EncryptResponse'); 
    RemClassRegistry.RegisterXSInfo(TypeInfo(DecryptResponse), 'http://dsws.org/protectappws/', 'DecryptResponse'); 
    RemClassRegistry.RegisterXSClass(Encrypt, 'http://dsws.org/protectappws/', 'Encrypt'); 
    RemClassRegistry.RegisterSerializeOptions(Encrypt, [xoLiteralParam]); 
    RemClassRegistry.RegisterXSClass(Decrypt, 'http://dsws.org/protectappws/', 'Decrypt'); 
    RemClassRegistry.RegisterSerializeOptions(Decrypt, [xoLiteralParam]); 

end. 

Ниже мой Delphi 7 код для вызова веб-сервиса.

unit Client; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs,ProtectappwsImpl, StdCtrls, Buttons, InvokeRegistry, Rio, 
    SOAPHTTPClient; 

type 
    TForm1 = class(TForm) 
    memResponse: TMemo; 
    memErrors: TMemo; 
    btnProcess: TBitBtn; 
    procedure btnProcessClick(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.btnProcessClick(Sender: TObject); 
var 
    ECrypt : Encrypt; 
    objService : protectappws; 
    wsResponse : WideString; 


    ProtectApp : protectappws; 
begin 
    memResponse.Lines.Clear; 
    memErrors.Lines.Clear; 
    memResponse.Refresh; 
    memErrors.Refresh; 
    try 
    ECrypt := Encrypt.Create; 


    ECrypt.username := 'kenwhite'; 
    ECrypt.password := 'kenwhite'; 
    ECrypt.keyname := 'MYKEY'; 
    ECrypt.plaintext := 'Hi'; 


    objService := Getprotectappws(True,EmptyStr,nil); 

    wsResponse := objService.Encrypt(ECrypt); 


    except 
    on E: Exception do 
    begin 
     showmessage(e.Message); 
    end; 
    end; 
end; 

end. 

когда я запускаю выше DELPHI кода я получаю ниже ошибки

'Unmarshalling Error: cvc-complex-type.2.4.a: Invalid content was found starting with element 'username'. One of '{username}' is expected

Delphi посылает ниже запроса на Java веб-службы

<?xml version="1.0"?> 

-<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 


-<SOAP-ENV:Body> 


-<Encrypt xmlns="http://dsws.org/protectappws/"> 

<username>kenwhite</username> 

<password>kenwhite</password> 

<keyname>MYKEY</keyname> 

<keyiv/> 

<transformation/> 

<plaintext>Hi</plaintext> 

</Encrypt> 

</SOAP-ENV:Body> 

</SOAP-ENV:Envelope> 

но вебсервис ожидает ниже запроса.

<?xml version="1.0"?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prot="http://dsws.org/protectappws/"><soapenv:Header/> 
    <soapenv:Body> 
     <prot:Encrypt><username>kenwhite</username> 
     <password>kenwhite</password> 
     <keyname>MYKEY</keyname> 
     <!--Optional:--> 
     <keyiv/> 
     <!--Optional:--> 
     <transformation/> 
     <plaintext>Hi</plaintext> 
     </prot:Encrypt> 
    </soapenv:Body> 
</soapenv:Envelope> 

Почему существует разница в запросе, вызванном Delphi, и клиент ожидает другого запроса.

я попытался удалить ioDocument снизу код и держать ioLiteral и наоборот

InvRegistry.RegisterInvokeOptions(TypeInfo(protectappws), ioDocument); 
    InvRegistry.RegisterInvokeOptions(TypeInfo(protectappws), ioLiteral); 

Delphi 7 генерирует запрос мыло с SOAP-ENV и Java ожидает soapenv. Я действительно смущен и застрял в этом.

+0

Спасибо! очень полезно. –

ответ

2

Чтобы устранить эту проблему, я изменил запрос на мыло.

В Delphi 7 произошла ошибка, поэтому я не мог изменить запрос на мыло. Чтобы исправить это, я загрузил Soapfix из embarcadero и изменил запрос soap onbeforeExecute для компонента HTTPRIO и начал работать. :)

перед изменением запроса нам просто нужно знать, что ожидает веб-сервис и изменить запрос.

с моей просьбы XML я просто удалил пространство имен с узла шифрования и работает.

<Encrypt xmlns="http://dsws.org/protectappws/"> 

Мой модифицированный запрос XML

<?xml version="1.0"?> 

-<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 

-<SOAP-ENV:Body> 

-<Encrypt> 

<username>kenwhite</username> 

<password>kenwhite</password> 

<keyname>MYKEY</keyname> 

<keyiv/> 

<transformation/> 

<plaintext>Hi</plaintext> 

</Encrypt> 

</SOAP-ENV:Body> 

</SOAP-ENV:Envelope> 
Смежные вопросы

 Смежные вопросы