SOAP and non-WSDL version

Hi All,

How to create WebService where response is like:


<?xml version="1.0" encoding="UTF-8"?>

   <SOAP-ENV:Envelope xmlns:SOAP-ENV="schemas.xmlsoap.org/soap/envelope/" 

                      xmlns:ns1="localhost/someService">

      <SOAP-ENV:Body>

         <ns1:someResponse>

            <ns1:someReturn>Return Message</ns1:someReturn>

         </ns1:someResponse>

      </SOAP-ENV:Body>

   </SOAP-ENV:Envelope>

Not like:


<?xml version="1.0" encoding="UTF-8"?>

<definitions xmlns="....">

...

</definitions>



Where I can find any information about that? I’m kind of newbie with SOAP.

Regards

The example above seems to be WSDL. Below is an example of a SOAP request/response messages (part of text strings removed).

Request




<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope

  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 

  xmlns:ns1="urn:ItemProviderwsdl" 

  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 

  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 

  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

  <SOAP-ENV:Body>

    <ns1:getCurrentItems/>

  </SOAP-ENV:Body>

</SOAP-ENV:Envelope>



Response




<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope

  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

  xmlns:ns1="urn:ItemProviderwsdl" 

  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 

  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

  <SOAP-ENV:Body>

    <ns1:getCurrentItemsResponse>

      <return SOAP-ENC:arrayType="xsd:string[5]" 

	    xsi:type="SOAP-ENC:Array">

	    <item xsi:type="xsd:string"> 0: ...</item>

	    <item xsi:type="xsd:string"> 1: ...</item>

	    <item xsi:type="xsd:string"> 2: ...</item>

	    <item xsi:type="xsd:string"> 3: ...</item>

	    <item xsi:type="xsd:string"> 4: ...</item>

      </return>

    </ns1:getCurrentItemsResponse>

  </SOAP-ENV:Body>

</SOAP-ENV:Envelope>



Read more about Web Services here

/Tommy

I know this. But still I don’t know how to get response with SOAP-ENV:Envelope.

Always when I’m doing request like:




$client = new SoapClient('http://localhost/index.php?r=test/data');

print_r($client->getData("hallo\n"));



Answer is: "hallo" without whole XML with SOAP-ENV:Envelope.

For me is ok. But this WebService should talk with some WebSphere or another java-something-app. Error is always the same: “Exception: org.xml.sax.SAXException: WSWS3066E: Error: Expected ‘envelope’ but found definitions”

I’m not an expert either, but this sounds like you didn’t specify the service address to the client in question (or at least the client didn’t use it in the call). That is, the url should end with &ws=1 (get format) or /ws/1 (path format).

BTW "hallo" is what you are expected to see. The data I posted was captured at network level.

/Tommy

Certainly not an expert ::)

It’s supplied in the wsdl response from the server




<definitions>

  ...

  <wsdl:service name="ItemProviderService">

    <wsdl:port name="ItemProviderPort" binding="tns:ItemProviderBinding">

      <soap:address location=".../item/itemsws/ws/1"/>

    </wsdl:port>

  </wsdl:service>

</definitions>



/Tommy

Ok. Here it is what I have.

The Server:




<?php

class TestController extends CController

{

	public function actions()

	{

		return array(

				'data' => array(

					'class' => 'CWebServiceAction',

					),

			);

	}


	/**

	 * @param string data to be returned

	 * @return string entered data

	 * @soap

	 */

	public function getData($param)

	{

		return $param;

	}

}



The Client:




<?php

$client = new SoapClient('http://localhost/index.php?r=test/data');

echo $client->getData("hallo");



Respond in browser after enter address: http://localhost/index.php?r=test/data




<?xml version="1.0" encoding="UTF-8"?>

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:TestControllerwsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" name="TestController" targetNamespace="urn:TestControllerwsdl">

	<wsdl:message name="getDataRequest">

		<wsdl:part name="param" type="xsd:string"/>

	</wsdl:message>

	<wsdl:message name="getDataResponse">

		<wsdl:part name="return" type="xsd:string"/>

	</wsdl:message>

	<wsdl:portType name="TestControllerPortType">

		<wsdl:operation name="getData">

			<wsdl:documentation></wsdl:documentation>

			<wsdl:input message="tns:getDataRequest"/>

			<wsdl:output message="tns:getDataResponse"/>

		</wsdl:operation>

	</wsdl:portType>

	<wsdl:binding name="TestControllerBinding" type="tns:TestControllerPortType">

		<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>

		<wsdl:operation name="getData">

			<soap:operation soapAction="urn:TestControllerwsdl#getData" style="rpc"/>

			<wsdl:input>

				<soap:body use="encoded" namespace="urn:TestControllerwsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

			</wsdl:input>

			<wsdl:output>

				<soap:body use="encoded" namespace="urn:TestControllerwsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

			</wsdl:output>

		</wsdl:operation>

	</wsdl:binding>

	<wsdl:service name="TestControllerService">

		<wsdl:port name="TestControllerPort" binding="tns:TestControllerBinding">

			<soap:address location="http://localhost/index.php?r=test/data&amp;ws=1"/>

		</wsdl:port>

	</wsdl:service>

</definitions>



Respond in browser after enter address: http://localhost/client.php




hallo



Java-something-app still gives exception: org.xml.sax.SAXException: WSWS3066E: Error: Expected ‘envelope’ but found definitions.

I can give only url to the WebService in this app - so I enter there: http://localhost/index.php?r=test/data

So where is my mistake that java-app get WSDL definitions instead of response of getData in envelope format?

Everything looks fine on the Yii side and the PHP SoapClient call. I don’t know the SAX project but I had a quick look and found out it wasn’t updated in 7 years. (The InputSource class has setters for a public and a system url. Just a guess, though.)

Perhaps consider a different client?

/Tommy

I cant’t, I must use this one and I can’t change anything in it. This client must call one method in mine server and I must find a way to give him data as he wants.

Maybe I should made some view with XML and insert there data to meet the requirement of format?

Have you been able to access some other (preferrably public) web service? Should be interesting to compare the WSDL.

/Tommy

I don’t have other examples of connection to this client.

What I know, is that I need a “stub” url for this client, which isn’t WSDL respond. How “stub” url should looks like in given earlier example?

Ok I have solution for this situation, when SoapClient is created with Axis2 and wants to connect to WS made with Yii.

First in CWebServiceAction.php in method run() following code:




if(isset($_GET[$this->serviceVar]))

    $this->_service->run();

else

    $this->_service->renderWsdl();



must looks like this:




//if(isset($_GET[$this->serviceVar]))

    $this->_service->run();

//else

//    $this->_service->renderWsdl();



Then in CWebService.php in method run() following line:




$server=new SoapServer($this->wsdlUrl,$this->getOptions());



must be changed into:




$options = $this->getOptions();

$options['uri'] = $this->wsdlUrl;

$server=new SoapServer(null,$options);



And now with example above, when Axis2 creating SoapClient with url to the service will have correct respond.

I think this should be changed with some parametrization or CWebService.php should also check if serviceVar is set - then SoapServer could be called with correct sets of params.

I know that uri can be passed by serviceOptions array, but I cant find other way to change wsdl into null than hack the run() method.

Hi i have implement the same thing but not able to call the methods getting exception no method found can you please suggest me what is the issue