Java server, PHP client, array of complexType, Deserializer error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This seems to be a recurring problem, but I have yet to find an answer.

I have implemented a web service written in Java, hosted on an Oracle Application Server (version 9.0.4).
The web service makes heavy use of custom objects, written as Java Beans on the server-side, and implemented as complex types in the WSDL.  The objects are really just collections of variables.

Using PHP 5.0.3 with its built-in SOAP implementation, I am able to consume the WSDL w/out errors and make most calls using PHP classes to emulate the WSDL's complex types.  The problem comes in when a transaction requires an array of one of the complex types.
Java-based clients have no problems; neither do .NET-based ones.

I built a simple example that illustrates the problem; let's get right into it.  This is a live example, so you can do some testing on your own if you'd like.

The service is here:
http://vrcweb1.vrcis.com/custserv/CustomerService
The WSDL can be found here:
http://vrcweb1.vrcis.com/custserv/CustomerService?WSDL

There is one operation: EchoBars.  It accepts an array of Bar objects, then returns that array.
The Bar object has one field: NAME, of type string.

This is the PHP code I use to invoke EchoBars:

$WSDL = "http://vrcweb1.vrcis.com/custserv/CustomerService?WSDL";;
$client = new SoapClient($WSDL);
$b1 = new Bar();
$b1->NAME = "bar none";
try{$client->EchoBars(array(1=>$b1));}catch(Exception $Ex){echo $Ex;}

This is the request it generates:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
  xmlns:ns1="CustomerService"
  xmlns:ns2="http://www.vrcis.com/CustomerServiceAPIV1";
  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/";
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";>
  <SOAP-ENV:Body>
    <ns1:EchoBars>
      <BARS
        SOAP-ENC:arrayType="ns2:Bar[1]"
        xsi:type="ns2:ArrayOfBar">
        <item xsi:type="ns2:Bar">
          <NAME xsi:type="xsd:string">bar none</NAME>
        </item>
      </BARS>
    </ns1:EchoBars>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Which request returns this error message:

No Deserializer found to deserialize a http://www.vrcis.com/CustomerServiceAPIV1:ArrayOfBar using encoding style http://schemas.xmlsoap.org/soap/encoding/.


Here is a request that works:

<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
  xmlns:xsd="http://www.w3.org/2001/XMLSchema";>
  <SOAP-ENV:Body>
    <ns1:EchoBars
      xmlns:ns1="CustomerService"
      SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";>
      <BARS
        xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/";
        xsi:type="ns2:Array"
        xmlns:ns3="http://www.vrcis.com/CustomerServiceAPIV1";
        ns2:arrayType="ns3:Bar[1]">
        <item xsi:type="ns3:Bar">
          <NAME xsi:type="xsd:string">bar none</NAME>
        </item>
      </BARS>
    </ns1:EchoBars>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Notice that the only real difference between the two requests is the type of the BARS element.  In the PHP-generated one it is "<my namespace>:ArrayOfBar", while it is "<SOAP-ENC namespace>:Array" in the other one.
There are other differences, but they are all naming conventions and don't apply.

To generate another request that works, goto http://www.soapclient.com/soaptest.html.  It'll generate a request that is substantively the same as the one above.

I think I know what's happening, I just don't know why, or if there's a way to make it "happen" correctly.  Or some way to reformat my WSDL so that PHP interprets it correctly.

The way I understand it, in the WSDL, arrays of complex types are defined with a level of indirection:

<complexType name="Bar">
</complexType>
<complexType name="ArrayOfBar">
  <attribute arrayType="Bar[]"/>
</complexType>

It seems to work kinda like pointers in C: ArrayOfBar holds a reference to an array of Bar objects.

What appears to be happening is that PHP is not following that reference, but is instead grabbing the value of the variable rather than dereferencing it and using _that_ value (to use pointer lingo).

So, my questions:

1. Is the WSDL formatted the right way for PHP?  Could it be formatted differently, so as to coerce PHP into supplying the correct "type" for the BARS element?
2. Is there any option or flag in PHP's SOAP implementation that will set up PHP to read the WSDL differently?
3. Does anyone know what the heck I'm talking about? ;-)

Thanks,

-Peter

-- 
PHP Soap Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[Index of Archives]     [PHP Home]     [PHP Users]     [Kernel Newbies]     [PHP Database]     [Yosemite]

  Powered by Linux