[gelöst] QtSoap und PHP SoapServer

Alles rund um die Programmierung mit Qt
Antworten
Grisu80
Beiträge: 43
Registriert: 14. September 2005 16:01
Wohnort: Münster

[gelöst] QtSoap und PHP SoapServer

Beitrag von Grisu80 »

Hallo zusammen,

ich habe auf meinem Rechner XAMPP installiert und dort ein php soap Servescript liegen. Der php-Client funktioniert ohne probleme.

Allerings bekomme ich den QtSoap-Client nicht zu laufen.
Der Service soll einfach 2 Zahlen addieren und als für den Client habe ich das Population beispielt aus den QtSoap beispielen verwendet.

Ich bekomme aber immer folgende fehlermeldung wenn der Client eine Antwort bekommt:
"Unknown error" "QtSoapMessage::OtherType"

Vielleicht kann mir ja jemand von euch weiterhelfen?

Gruß,
Sebastian

TestClient.cpp

Code: Alles auswählen


#include <QtGui/QApplication>
#include "TestClient.h"

TestClient::TestClient(QObject *parent)
    : QObject(parent), http(this)
{
    // Connect the HTTP transport's responseReady() signal.
    connect(&http, SIGNAL(responseReady()), this, SLOT(getResponse()));

    // Construct a method request message.
    QtSoapMessage request;

    // Set the method and add one argument.
    request.setMethod("addiere", "urn:xmethodsTestServer");
    request.addMethodArgument("sum1", "", "10");
    request.addMethodArgument("sum2", "", "30");
    qDebug()<<"Request"<<request.toXmlString();
    // Submit the request the the web service.
    http.setHost("localhost");
    http.setAction("urn:xmethodsTestServer#addiere");
    http.submitRequest(request, "/soap/server");
}

void TestClient::getResponse()
{
    // Get a reference to the response message.
    const QtSoapMessage &message = http.getResponse();

    // Check if the response is a SOAP Fault message
    if (message.isFault()) {
        qDebug("Error: %s", message.faultString().value().toString().toLatin1().constData());
    }
    else {
        // Get the return value, and print the result.
        const QtSoapType &response = message.returnValue();
    }
    qApp->quit();
}
TestClient.h

Code: Alles auswählen

#include <qtsoap.h>

class TestClient : public QObject
{
    Q_OBJECT
public:
    TestClient(QObject *parent = 0);

private slots:
    void getResponse();

private:
    QtSoapHttpTransport http;
};
main.cpp

Code: Alles auswählen

#include <QtGui/QApplication>
#include "TestClient.h"

int main(int argc, char **argv)
{
    QApplication app(argc, argv, false);

    TestClient pop(0);

    return app.exec();
}
Außerdem habe ich hier noch die wsdl und die server.php
Das ist ein beispiel aus:

http://www.tutorials.de/php-tutorials/1 ... -soap.html

server.php

Code: Alles auswählen

<?php
function  addiere($sum1, $sum2) {
    return $sum1 + $sum2;
}

$server = new SoapServer("testserver.wsdl",
 array('uri' => "localhost",
       'soap_version' => SOAP_1_1));                //{uri} müsst ihr ersetzen mit den pfad 
$server->addFunction('addiere');            //Funktion zum Server hinzufügen
$server->handle();                     //Hier wird die Abfrage abgearbeitet
?> 
[/code]

testserver.wsdl

Code: Alles auswählen

 
<?xml version ='1.0' encoding ='UTF-8' ?> 
<definitions name='TestServer' 
  xmlns:tns=' [url]http://localhost/soap/testserver.wsdl[/url] ' 
  xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' 
  xmlns:xsd='http://www.w3.org/2001/XMLSchema' 
  xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/' 
  xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/' 
  xmlns='http://schemas.xmlsoap.org/wsdl/'> 
 
<message name='addiereAnfrage'> 
  <part name='sum1' type='xsd:float'/>
  <part name='sum2' type='xsd:float'/>
</message> 
<message name='addiereAntwort'> 
  <part name='Result' type='xsd:float'/> 
</message> 
 
<portType name='TestServerPortType'> 
  <operation name='addiere'> 
    <input message='tns:addiereAnfrage'/> 
    <output message='tns:addiereAntwort'/> 
  </operation> 
</portType> 
 
<binding name='TestServerBinding' type='tns:TestServerPortType'> 
  <soap:binding style='rpc' 
    transport='http://schemas.xmlsoap.org/soap/http'/> 
  <operation name='addiere'> 
    <soap:operation soapAction='urn:xmethodsTestServer#addiere'/> 
    <input> 
      <soap:body use='encoded' namespace='urn:xmethodsTestServer' 
        encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> 
    </input> 
    <output> 
      <soap:body use='encoded' namespace='urn:xmethodsTestServer' 
        encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> 
    </output> 
  </operation> 
</binding> 
 
<service name='TestServerService'> 
  <port name='TestServerPort' binding='TestServerBinding'> 
    <soap:address location='http://localhost/soap/server.php'/> 
  </port> 
</service> 
</definitions>
Zuletzt geändert von Grisu80 am 25. Oktober 2010 21:55, insgesamt 1-mal geändert.
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: QtSoap und PHP SoapServer

Beitrag von solarix »

Grisu80 hat geschrieben: Ich bekomme aber immer folgende fehlermeldung wenn der Client eine Antwort bekommt:
"Unknown error" "QtSoapMessage::OtherType"
Der "Unknown error" ist in Qt eigentlich immer der "Default Error" oder besser gesagt von der Bedeutung her "Kein Error".
Sieh dir mal den Konstruktor an, dann weisst du was ich meine:

http://code.google.com/p/omapd/source/b ... svn37&r=37

Auch der "OtherType" kann dort (nach einem "isFault()") eigentlich gar nicht kommen, weil "isFault()" ja nur "true" liefert, wenn eben KEIN OtherType anliegt:

Code: Alles auswählen

bool QtSoapMessage::isFault() const
{
    return faultCode() != Other;
}
Ich misstraue aber eher deiner Fehlerausgabe.. versuch mal alles auszugeben was du kriegen kannst, damit du allenfalls eine genauere Fehlerbeschreibung bekommst:

Code: Alles auswählen

if (message.isFault()) {
        qDebug() << "SoapError: " <<  message.faultCode()
                                         << message.faultDetail().errorString()
                                         << message.faultString().errorString()
                                         <<  message.errorString()
} 
hth..
Grisu80
Beiträge: 43
Registriert: 14. September 2005 16:01
Wohnort: Münster

Beitrag von Grisu80 »

Hi,
ich hätte mal meinen Debugger weiterlaufen lassen sollen, aber wirklich hilft mir das auch nicht weiter

Code: Alles auswählen

qDebug("Error: %s", message.faultString().value().toString().toLatin1().constData());
Ergibt: SOAP structure invalid

Die neue Ausgaben helfen mir leider auch nicht:

SoapError: 0 "Unknown error" "Unknown error" "Unknown error"


Da ich noch sehr neu in SOAP bin habe ich hier mal die erzeugte Nachricht, vielleicht erkennt ja jemand hier den Fehler:

Code: Alles auswählen

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<addiere xmlns="urn:xmethodsTestServer">
<sum1 xsi:type="xsd:int" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">10</sum1>
<sum2 xsi:type="xsd:int" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">30</sum2>
</addiere>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

mir fallen zwei Dinge auf die ich an deiner Stelle abklären würde:

1. Wenn du den ErrorCode "0" erhälst, müsste das doch "QtSoapMessage::VersionMismatch" bedeuten.. oder? Die Qt-Library ist für v1.1... läuft der (PHP)Server auch unter dieser Version?

2. Beim Argument bin ich etwas verwirrt... du übergibst im Grunde ein String ("30"), tatsächlich übergeben wird ein Integer (<sum1 xsi:type="xsd:int" ....) und vom Server erwartet wird ein Float... geht denn das? Oder solltest du dort nicht besser ein Argument vom Typ "QtSoapType::Float" übergeben?

hth..
Grisu80
Beiträge: 43
Registriert: 14. September 2005 16:01
Wohnort: Münster

Beitrag von Grisu80 »

1. Wenn du den ErrorCode "0" erhälst, müsste das doch "QtSoapMessage::VersionMismatch" bedeuten.. oder? Die Qt-Library ist für v1.1... läuft der (PHP)Server auch unter dieser Version?
Hi, in der server.php habe ich beim anlegen des servers eigentlich angegeben das SOAP_1_1 verwendet werden soll, ob das wirklich funktioniert ist mir nicht klar. vielleicht sollte ich da noch mal in einem PHP-Forum nachfragen.

2. Beim Argument bin ich etwas verwirrt... du übergibst im Grunde ein String ("30"), tatsächlich übergeben wird ein Integer (<sum1 xsi:type="xsd:int" ....) und vom Server erwartet wird ein Float... geht denn das? Oder solltest du dort nicht besser ein Argument vom Typ "QtSoapType::Float" übergeben?
Ich habe gestern abend noch die wsdl angepasst und xsd:int eingetragen, und ich habe die übergabe auf Integer geändert.

Das ist alles eine ganz schön unübersichtliche Sache.
Ich habe ja den Eindruck das es ein Problem mit der URI beim setMethod gibt.

Ich werde noch weiter experimentieren wenn ich wieder zu hause bin.

Vielen dank für die Hilfe,

Sebastian
Grisu80
Beiträge: 43
Registriert: 14. September 2005 16:01
Wohnort: Münster

Beitrag von Grisu80 »

Problem ist gelöst :D

Hier war der Fehler:

Code: Alles auswählen

http.submitRequest(request, "/soap/server"); 
nachdem ich die Endung php angehängt funktioniert es:

Code: Alles auswählen

http.submitRequest(request, "/soap/server.php"); 

Was mich allerdings wundert ist folgendes:

Code: Alles auswählen

const QtSoapType &response = message.returnValue();
qDebug()<<"response error:"<<response.errorString();
Hier wird immer "Unknown error" ausgegeben.

Aber was solls, Problem ist gelöst :D
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Ja... bei SOAP gibt's viiiiele Kleinigkeiten zu beachten :wink:

"Unknown error": ich hab bereits erwähnt, dass dies der "Default-Error", also "Kein Fehler" ist.. daher: Error-Strings (egal ob hier oder z.B. in Datenbank-Klassen) sollten nur abgefragt werden, wenn auch ein Fehler anliegt...!


"Problem ist gelöst": Thread-Titel noch auf "[gelöst]" ... :wink:
Antworten