PHP Forum

PHP Forum (http://www.selfphp.de/forum/index.php)
-   PHP Grundlagen (http://www.selfphp.de/forum/forumdisplay.php?f=12)
-   -   Webservice einrichten (http://www.selfphp.de/forum/showthread.php?t=22363)

rencarl 06.11.2009 16:25:14

Webservice einrichten
 
Hi,

für einen Kooperationspartner soll ich einen Webservice einrichten, mit dem Daten im XML-Format an den Webservice gesendet werden können.

Hier ein Beispiel, wie die Daten ankommen:
HTML-Code:

<?xml version="1.0" encoding="UTF-8"?><OTA_HotelInvCountNotifRQ xmlns="http://www.opentravel.org/OTA/2003/05" TimeStamp="2009-10-14T17:17:45" Target="Production" Version="1"><POS><Source AgentDutyCode="agentdutycode" AgentSine="agentsine"><RequestorID ID="199976"/></Source></POS><Inventories><Inventory><StatusApplicationControl Start="2009-10-14" End="2009-11-10" InvTypeCode="140759" /><InvCounts><InvCount Count="60" CountType="1" /></InvCounts></Inventory><Inventory><StatusApplicationControl Start="2009-11-10" End="2009-11-11" InvTypeCode="140759" /><InvCounts><InvCount Count="0" CountType="1" /></InvCounts></Inventory><Inventory><StatusApplicationControl Start="2009-11-11" End="2009-11-12" InvTypeCode="140759" /><InvCounts><InvCount Count="60" CountType="1" /></InvCounts></Inventory><Inventory><StatusApplicationControl Start="2009-11-12" End="2009-11-13" InvTypeCode="140759" /><InvCounts><InvCount Count="0" CountType="1" /></InvCounts></Inventory><Inventory><StatusApplicationControl Start="2009-11-13" End="2010-10-15" InvTypeCode="140759" /><InvCounts><InvCount Count="60" CountType="1" /></InvCounts></Inventory></Inventories></OTA_HotelInvCountNotifRQ>
Mein aktueller Wissensstand zum Thema Webservice basiert auf folgendem Beispiel (Punkt 6):http://www.tutorials.de/forum/php-tu...tieg-soap.html

Zusätzlich weiß ich, dass ich die XML-Daten mittels curl versenden und mit Simple-XML auswerten kann. Aber soweit bin ich noch gar nicht.

Ich möchte den Webservice natürlich vorher testen, nur weiß ich nicht, wo ich anfangen soll. Ich habe bereits ein wenig rumprobiert. PHP bietet z. B. einige nützliche Methoden, wie z. B. '__getLastRequest'. Nur erhalte ich bei den Methoden stets eine leere Ausgabe, keine Fehlermeldung oder sonstwas. Damit kann ich nichts anfangen und ich komme an der Stelle nicht weiter. Das ist ziemlich frustrierend, wenn man nicht weiß, was man falsch macht.

Daher stellen sich mir auch einige Fragen:
- Benötige ich zwingend eine WSDL-Datei?
- Wie erhalte ich eine verwertbare Ausgabe (Fehlermeldung oder sonst was, Hauptsache irgendwas) der PHP-SOAP-Methoden?
- Da im XML-Request kein Funktionsname angegeben ist, wie werte ich den XML-Request überhaupt aus bzw. wie übergebe ich den XML-Code an eine Funktion, die den XML-Code auswertet?

Danke und Gruß

urvater 06.11.2009 21:07:40

AW: Webservice einrichten
 
Zitat:

Zitat von rencarl (Beitrag 131999)
Daher stellen sich mir auch einige Fragen:
- Benötige ich zwingend eine WSDL-Datei?

Sie benutzen die Scriptsprache XML und definieren alles, um es euch zu erleichtern, diesen Service zu benutzen.

Somit benötigst du diese Dateien, wenn du dem Tutoriel folgen willst bzw. wenn du die gleiche Grundlage in deinem Script verwenden willst.
Zitat:

Zitat von rencarl (Beitrag 131999)
- Wie erhalte ich eine verwertbare Ausgabe (Fehlermeldung oder sonst was, Hauptsache irgendwas) der PHP-SOAP-Methoden?

9. Fehlerbehandlung in SOAP
Zu guter Letzt schreibe ich noch was zur Fehlerhandhabung.
Nehmen wir mal ein Beispiel. Du stellst ein Skript als SOAP-Server zu Verfüguung, welches in einer Datenbank nach Artikeln sucht. Nun gibt der Client aber keine Artikelbeschreibung an, wonach es dir nicht möglich ist, diese Abfrage durchzuführen. Dafür stellt SOAP extra ein Errorhandler bereit, wo man Errorcodes zurück an den Clienten schicken kann.
Bauen wir es am Besten gleich mal in unseren TestServer ein:

Ab Punkt 9 erklärt der Autor dir wie es geht.
Zitat:

Zitat von rencarl (Beitrag 131999)
- Da im XML-Request kein Funktionsname angegeben ist, wie werte ich den XML-Request überhaupt aus bzw. wie übergebe ich den XML-Code an eine Funktion, die den XML-Code auswertet?

Danke und Gruß

Auf Deutsch heisst das, dass hier festgelegt wird, dass die Message "BabelFishRequest" der Funktionsaufruf an den Server ist (Eingangsnachricht) und die Message "BabelFishResponse" den Rückgabewert darstellt (Ausgangsnachricht). Nun zu den Message-Zeilen darüber. Dort werden die einzelnen Nachrichten definiert. Mit der Eigenschaft "name" wird der Name für diese Nachricht festgelegt.

An dieser Stelle beschreibt er, wie der Request ausgewertet wird. Lt. Tutoriel erfolgt hier ein Funktionsaufruf.

rencarl 10.11.2009 10:47:01

AW: Webservice einrichten
 
Hi, erst mal danke für die Antwort.

Ich habe das Tutorial nochmal durchgearbeitet und mir die WSDL-Datei erstellt. Funktioniert soweit ganz gut.

Dabei ist mir folgendes aufgefallen: Wenn in der WSDL der Pfad zum Webservice angegeben wird
Code:

<service name='TestServerService'>
  <port name='TestServerPort' binding='TestServerBinding'>
    <soap:address location='http://www.url.de/webservices/server.php5' />
  </port>
</service>

und im Client folgender Aufruf erfolgt
PHP-Code:

$client = new SoapClient('http://www.url.de/webservices/wsdl/BensersielService.wsdl'); 

funktioniert es nicht. Ich erhalte eine Fehlermeldung "Could not connect to host". Gebe ich aber im Client folgendes an:
PHP-Code:

$client = new SoapClient('http://www.url.de/webservices/wsdl/BensersielService.wsdl',array("location" => "http://www.url.de/webservices/server.php5")); 

funktioniert es. Wo liegt da der Fehler?

Wie ich mittlerweile herausgefunden habe, muss man das Resultat der PHP-SOAP-Methoden, wie z. B. __getLastRequest, in <xmp></xmp> einfassen, damit man eine Ausgabe im Browser erhält.

Nun aber weiter mit meinem Webservice. Ich möchte den im Threadstart genannten XML-Code an den zukünftigen Webservice senden. Die noch nicht für den Webservice angepasste WSDL-Datei ist unter http://www.nordseetraum.de/webservic...elService.wsdl zu finden.
Der Webservice hat derzeit noch folgenden Aufbau:
PHP-Code:

<?php
// Fehlermeldungen anzeigen
error_reporting(E_ALL);

function  
addiere($sum1$sum2) {
   if(isset(
$sum1) && isset($sum2))
      return 
$sum1 $sum2;
   else
      return new 
SoapFault('Client''Eingabe nicht korrekt''server.php5''');
}

$server = new SoapServer(NULL,
 array(
'uri' => "http://www.nordseetraum.de/webservices/"));
$server->addFunction('addiere');            //Funktion zum Server hinzufügen
$server->handle();                     //Hier wird die Abfrage abgearbeitet
?>

Im Client sende ich mittels curl den XML-String an den Webservice:
PHP-Code:

$body 'XML-String aus Threadstart';

$headers = array(
"Content-Type: text/xml;charset=UTF-8",
"SOAPAction: \"urn:addiere\"");

//1. Die Session initialisieren
$ch curl_init();

//2 . Session Optionen setzen
curl_setopt($chCURLOPT_HTTPHEADER$headers);
curl_setopt($chCURLOPT_URL"http://www.nordseetraum.de/webservices/server.php5");

curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE); // Immer setzen, wenn kein Zertifikat vorhanden
curl_setopt($chCURLOPT_SSL_VERIFYHOSTFALSE);

curl_setopt($chCURLOPT_POSTFIELDS$body);
curl_setopt($chCURLOPT_RETURNTRANSFERTRUE);

//3. Ausführen der Aktionen
$result curl_exec($ch);

if(
$result === false){
   echo 
'<p>Fehler: '.curl_error($ch);
} else {
   echo 
'<p>Ergebnis: '.$result;
   
   
$info curl_getinfo($ch);
   
//foreach($info AS $k => $v)
     // echo '<p>'.$k.' => '.$v;
   
}

//4. Session beenden
curl_close($ch); 

Ich bekomme keinen curl-Fehler ausgegeben. Die Übertragung scheint also zu funktionieren. Als Ausgabe erhalte ich
HTML-Code:

Ergebnis: SOAP-ENV:VersionMismatchWrong Version
. Und das Ganze in XML-Form:
HTML-Code:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:VersionMismatch</faultcode><faultstring>Wrong Version</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

Das es nicht funktionieren kann ist klar. Aber da ich keine Erfahrung habe, weiß ich nicht genau, wie ich weiter vorgehen kann/muss/sollte. Und wie es immer so ist, man hat wenig Zeit sich mit der Materie intensiver auseinanderzusetzen. Deshalb frage ich jemanden, der sich damit auskennt ;-)

Ich würde als nächstes erst mal die WSDL-Datei anpassen wollen, damit ich den Fehler "VersionMismatchWrong Version" wegbekomme. Wo kann da die Ursache liegen? Ich habe gelesen, dass es am falschen Namespace liegen kann oder am fehlenden Root-Element "ENVELOPE". Wie und wo muss ich das in der WSDL-Datei angeben?

rencarl 10.12.2009 19:00:11

AW: Webservice einrichten
 
Hi, ich bin mittlerweile schon mal einen Schritt weiter. Da ich sehr wenig Erfahrung mit Webservices habe, bin ich bisher davon ausgegangen, dass der Kunde uns die Daten im korrekten Format sendet.

Folgende Erkenntnisse habe ich erlangt:

Wird ein Request im folgenden Format gesendet:
HTML-Code:

<OTA_HotelInvCountNotifRQ xmlns="http://www.opentravel.org/OTA/2003/05" TimeStamp="2009-10-14T17:17:45" Target="Production" Version="1">
<POS>
<Source AgentDutyCode="agentdutycode" AgentSine="agentsine"><RequestorID ID="199976"/></Source>
</POS>
<Inventories>
 <Inventory>
 <StatusApplicationControl Start="2010-04-14" End="2010-05-10" InvTypeCode="140759" />
 <InvCounts><InvCount Count="60" CountType="1" /></InvCounts>
 </Inventory>
 <Inventory>
 <StatusApplicationControl Start="2010-11-10" End="2010-11-11" InvTypeCode="140759" />
 <InvCounts><InvCount Count="0" CountType="1" /></InvCounts>
 </Inventory>
</Inventories>
</OTA_HotelInvCountNotifRQ>

erhalte ich eine Fehlermeldung "Version Mismatch".

Wird ein Request aber mit Envelope gesendet:
HTML-Code:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header></soap:Header>
<soap:Body>
<OTA_HotelInvCountNotifRQ xmlns="http://www.opentravel.org/OTA/2003/05" TimeStamp="2009-10-14T17:17:45" Target="Production" Version="1">
...
</OTA_HotelInvCountNotifRQ>
</soap:Body>
</soap:Envelope>

funktioniert der Webservice wunderbar.

Bevor ich dem Kunden jetzt mitteile, dass er doch bitte seinen Request ändern soll, habe ich noch ein paar Fragen.

Ist es irgendwie anders möglich den Request ohne Envelope zu verwenden, so dass der Kunde seinen Request nicht ändern muss? Gibt es vielleicht eine Möglichkeit den Server entsprechend einzustellen? Oder gibt es vielleicht eine andere Technologie? XML-RPC vielleicht (hab ich nebenbei von gelesen)?

Mein Server sieht wie folgt aus:
PHP-Code:

<?php
// Fehlermeldungen anzeigen
error_reporting(E_ALL);

// Hauptklasse
require("class/VacData.class.php");

$vac = new VacData;

// DB-Verbindung herstellen
require($vac->htdocs."/db/opendb.inc.php");

try{
   
$server = new SoapServer(NULL, array(
   
"uri" => "http://www.opentravel.org/OTA/2003/05",
   
"location" => "http://www.url.de/webservices/server.php5"));
   
//$server->addFunction('OTA_HotelInvCountNotifRQ');
   
$server->setClass("VacData");
   
$server->handle();
}
catch (
SOAPFault $f) {
  print 
$f->faultstring;
}
?>



Alle Zeitangaben in WEZ +2. Es ist jetzt 16:37:05 Uhr.

Powered by vBulletin® Version 3.8.3 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.