WSDL, Apache CXF und soapUI

  • Themenstarter Themenstarter zzuegg
  • Beginndatum Beginndatum
Z

zzuegg

Gast
Hallo miteinander.
Zur Betriebsführung mache ich mir gerade ein Programm welches die Daten direkt zur Hauptverwaltung sendet. Die Vewaltung war auch so nett eine SOAP Schnittstelle zur Verfügung zu stellen. Leider bin ich ein totaler SOAP anfänger.

Der Start war recht einfach, und die ersten Interaktionen (Login/Logout) funktionierten tadellos.

Leider gingen die interaktionen mit komplexeren rückgaben nichtmehr. Nach etlichen vesuchen mit AXIS, CFX und so weiter bin ich nun bei einer konfiguration gelandet welcher mir vom Handling am besten zusagt.

Mit dem Netbeans plugin swingUI kann man sich wunderbaren CFX code generieren welcher sich dann einfach nutzen lässt.

Leider funktionieren auch hier die Abfragen mit komplexeren rückgabewerten nicht.

Die Abstraktion der daten funktioniert leider nur bis zu einem bestimmten Bereich. Danach bekomme ich nur noch leere Objecte anstatt 'vollen' klassen.

Mittlerweile gehe ich davon aus dass die WSDL datei nicht vollständig ist.
Das Problem besteht darin dass einige Datentypen in einer separaten .xsd datei zu finden sind, diese Datei wird jedoch nirgens in der WSDL referenziert.

Ist meine Annahme korreckt? Und wenn ja gibt es eine Möglichkeit das Problem einigermasen sauber zu lösen?

WSDL+beispiel .xsd hier auf pastebin, da der text sonst zu lang für einen Post wird: -> [XML] WSDL: [XML] <?xml version="1.0" encoding="utf-8"?> <wsdl:definitions xmlns:so - Pastebin.com

Danke schon mal im voraus für Eure hilfe.

Michael
 
Bei welchen der Elemente aus der XSD bist du denn der Meinung, dass sie fehlen?


Ich habe mit hier gerade mit wsimport -extension die Artefakte generiert und zumindest dabei hat er nichts fehlendes bemängelt.

Hast du die XSD auch von der Verwaltung bekommen?
 
Bei welchen der Elemente aus der XSD bist du denn der Meinung, dass sie fehlen?


Ich habe mit hier gerade mit wsimport -extension die Artefakte generiert und zumindest dabei hat er nichts fehlendes bemängelt.

Hast du die XSD auch von der Verwaltung bekommen?

Hallo, erstmal vielen dank fuer die Antwort.
Ja, die XSD kommt auch von der Verwaltung.

Das problem scheint, dass die XSD nicht mit der WDSL verbunden ist, der aufruf 'getStammdaten' sollte eine rueckgabe vom typ 'Stammdaten' (definieiert in der XSD) bringen. Die rueckgabe der funktion ist in der wsdl jedoch nur als complextype/any definiert ohne referenz zur XSD.

Der generierte code liefert bei 'getStammdaten' nur eine List(Object) mit einem 'null' element.
 
Also fehlt doch nichts 😉.


Nein, keine Ahnung. Vielleicht hat der jeweilige Verantwortliche die XSD auch nur dazu benutzt, sich über jaxb Domainobjekte zur leichteren Handhabung zu generieren.
Ich finde die Schnittstelle eh irgendwie nur mäßig gut definiert (vom allgemeinen Entwurf abgesehen, bevorzuge ich bspw. zum Fehlerhandling noch so etwas wie ServiceFaults).

Von daher solltest du dir vielleicht von der Verwaltung mal Daten geben lassen, die auf jeden Fall funktionieren.
Mit diesen Daten stellst du dann erstmal Anfragen mit SoapUI um erstmal ein Gefühl für den allgemeinen Ablauf zu bekommen (ohne cxf und netbeans).
 
Also fehlt doch nichts 😉.


Nein, keine Ahnung. Vielleicht hat der jeweilige Verantwortliche die XSD auch nur dazu benutzt, sich über jaxb Domainobjekte zur leichteren Handhabung zu generieren.
Ich finde die Schnittstelle eh irgendwie nur mäßig gut definiert (vom allgemeinen Entwurf abgesehen, bevorzuge ich bspw. zum Fehlerhandling noch so etwas wie ServiceFaults).

Von daher solltest du dir vielleicht von der Verwaltung mal Daten geben lassen, die auf jeden Fall funktionieren.
Mit diesen Daten stellst du dann erstmal Anfragen mit SoapUI um erstmal ein Gefühl für den allgemeinen Ablauf zu bekommen (ohne cxf und netbeans).

Naja die Fehlercodes sind schon definiert, nur wieder in einer separaten xsd datei, welche nicht referenziert wird.
Ich habe funktionierende Date, die manuelle XML übertragung funktioniert auch einwandfrei, jedoch kann ich mir keinen (funktionierenden) Service compilieren, da die rückgabewerte nicht definiert/referenziert sind.
Als Lösung würde sich anbieten die WSDL so umzuschreiben dass die rückgabewerte definiert werden. (Einfach den xsd inhalt in den entsprechnenden Bereich kopieren?), oder wie gesagt die XML's manuell zu parsen. Natürlich möglich jedoch für die komplexeren daten sehr umständlich?

Was würdes du machen?
 
Ich meinte nicht Fehlercodes sondern Faults (also quasi das Service-Pendant zu Exceptions) .

Wie sprichst du denn den Webservice an (also was machst du bei: "die manuelle XML-Übertragung funktioniert auch einwandfrei")?

Und kennst du die Laufzeitumgebung des Webservices? Applikationserver stellen normalerweise auch die jeweilige WSDL zum Endpunkt bereit. Von dieser kannst du dir dann auch die Artefakte für einen Client generieren.
 
Ich meinte nicht Fehlercodes sondern Faults (also quasi das Service-Pendant zu Exceptions) .

Wie sprichst du denn den Webservice an (also was machst du bei: "die manuelle XML-Übertragung funktioniert auch einwandfrei")?

Und kennst du die Laufzeitumgebung des Webservices? Applikationserver stellen normalerweise auch die jeweilige WSDL zum Endpunkt bereit. Von dieser kannst du dir dann auch die Artefakte für einen Client generieren.

Die oben gepostete WSDL wird vom Applikationsserver zur verfügung gestellt. Manuell heisst für mich, entweder mit einem simplen post request, oder über soapUI.

Laufzeitumgegung kenne ich nicht.

Das einzige problem welches ich glaube zu haben, ist dass in der WSDL, folgenes element:
[XML]
<s:element name="getStammdatenResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="getStammdatenResult">
<s:complexType mixed="true">
<s:sequence>
<s:any/>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
[/XML]

definiert ist, leider funktioniert die umwandlung von <s:any/> nicht. Im endeffekt sollte hier nach meinem jetzigen verständniss (Was bezüglich SOAP nicht viel ist) sowas wie
[XML]
<s:element name="getStammdatenResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="getStammdatenResult">
<s:complexType mixed="true">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Stammdaten" type="m:Stammdaten"/>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
[/XML]

stehen, mit bezug zum element stammdaten aus der xsd.
Leider finde ich gerade auch keinen weg um die XSD einzubinden, habe es mit
[XML]
xmlns:m="https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/stammdaten.xsd"
[/XML]
im header versucht. Jedoch bleibt m:Stammdaten nicht gültig...
 
Also bei mir generiert er die Artefakte und - wie ich meine - auch richtig.

Aus

[XML] <s:element minOccurs="0" maxOccurs="1" name="massnahmen">
<s:complexType mixed="true">
<s:sequence>
<s:any />
</s:sequence>
</s:complexType>
</s:element>
[/XML]

generiert er dann eine innere Klasse Massnahmen über deren Methode getContent() ich dann auf eine Liste von Object zugreifen kann.


Ich vermute wie - glaube ich - schonmal sagte, dass der jeweilige Entwickler sich über JAXB aus der XSD die Objekte separat generiert. Da die Liste ja Objekte vom Typ Object entgegennimmt, kann er diese dann auch über den Webservice versenden und empfangen.


Möchtest du konsistent zu seiner Implementierung bleiben. Machst du es genauso.

Wenn du eine saubere Lösungen haben willst, solltest du dir:

How to Import XSD Into WSDL | eHow.com

ansehen und der Hausverwaltung einen Gang einlegen 😉
 
Also bei mir generiert er die Artefakte und - wie ich meine - auch richtig.

Aus

[XML] <s:element minOccurs="0" maxOccurs="1" name="massnahmen">
<s:complexType mixed="true">
<s:sequence>
<s:any />
</s:sequence>
</s:complexType>
</s:element>
[/XML]

generiert er dann eine innere Klasse Massnahmen über deren Methode getContent() ich dann auf eine Liste von Object zugreifen kann.


Ich vermute wie - glaube ich - schonmal sagte, dass der jeweilige Entwickler sich über JAXB aus der XSD die Objekte separat generiert. Da die Liste ja Objekte vom Typ Object entgegennimmt, kann er diese dann auch über den Webservice versenden und empfangen.


Möchtest du konsistent zu seiner Implementierung bleiben. Machst du es genauso.

Wenn du eine saubere Lösungen haben willst, solltest du dir:

How to Import XSD Into WSDL | eHow.com

ansehen und der Hausverwaltung einen Gang einlegen 😉

Hallo, das erzeugen der klassen mit jaxb hat wunderbar funktioniert.
Bis zum getContent() bin isch schon immer gekommen. Leider habe ich angenommen dass es da ein getStammdaten() braucht.

Mein neues problem, wie wandle die List<Object> von getContent() in mein gewünschtes object um?

mit folgendem code:

Java:
            XWSNutriExchangeServiceSoap client = new XWSNutriExchangeService().getXWSNutriExchangeServiceSoap12();
            
            String ticket=client.logIn("dummyUser", "dummyPassword", "dummySwKey");
            System.out.println(ticket);
            List<Object> objects=client.getStammdaten(ticket).getContent();
            List<Stammdaten> stammdaten=new ArrayList<Stammdaten>();
            for(Object o:objects){
                stammdaten.add((Stammdaten)o);
            }
bekommen ich immer eine cast exception:

Java:
26.06.2012 21:06:55 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
INFO: Creating Service {http://localhost/nutriWebServices/v0003}XWSNutriExchangeService from WSDL: [url]https://www.betriebsheft.vip.coop/release/nutriwebservices/v0003/NutriExchangeService.asmx?WSDL[/url]
32010dd0-e4e8-4e63-8492-37dc7943a0d4
Exception in thread "main" java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to Applications.ZAppStammdaten.Data.Stammdaten.Stammdaten
	at Executables.Test.VipSOAP_TEST.main(VipSOAP_TEST.java:41)
Java Result: 1
 
Vergiss den letzten post, ich muss natürlich den unmarshaller benützten.

Funktioniert alles. Danke 1000mal für deine hilfe
 

Zurück
Oben