Java/Oracle server, PHP 5.1.2 client, array of complexTypes, Deserializer error

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

 



I posted this last night, but it hasn't shown up, so I'm posting it again...
My apologies if this ends up being a double post.

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.

Using PHP 5.1.2 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 is 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).


Naturally, the server replies (to the PHP-generated request), "I have no
idea what an 'ArrayOfBar'-type object is".

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. Is there a better way (other than an array) to implement a parameter that
is a collection of complexTypes?
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