Loading ...
Sorry, an error occurred while loading the content.

Sending array of arrays between SOAP::Lite and Java

Expand Messages
  • dfg778
    I m having a lot of difficulty sending an array of arrays between a SOAP::Lite server and a Java (Apache SOAP) client. My client has the following: sub getLoL
    Message 1 of 2 , Mar 10, 2003
    • 0 Attachment
      I'm having a lot of difficulty sending an array of arrays between a
      SOAP::Lite server and a Java (Apache SOAP) client. My client has the
      following:

      sub getLoL {

      my @LoL = ( [qw(a b c d)], [qw(d e f g)]) ;
      my @SOAPLoL ;
      foreach $row (@LoL) {
      my (@SOAProw, $i) ;
      foreach $col (@{$row}) {
      $col = SOAP::Data->name("col".++$i)->type('string')->value
      ($col) ;
      push @SOAProw,$col ;
      }
      push @SOAPLoL,SOAP::Data->name("row")->type('Hashtable')->value
      (\@SOAProw) ;
      }
      my $output = SOAP::Data->name('LoL')->type('Vector')->value
      (\@SOAPLoL) ;
      #my $output = SOAP::Data->name('LoL' => \@LoL)->type ;
      #my $output = \@LoL ;
      return $output ;
      }

      I've been through several iterations of this, having to get more and
      more specific every time. If I just return the reference to the
      array, the Java client gives me:

      Unable to resolve namespace URI for '~C'

      (it's complaining about an array type specification of ~C:Array in
      the Soap packet, the appropriate fragment is below)

      <SOAP-ENV:Body><namesp2:getLoLResponse xmlns:namesp2="urn:Demo"><SOAP-
      ENC:Array SOAP-ENC:arrayType="~C:Array[2]" xsi:type="SOAP-
      ENC:Array"><s-gensym9 SOAP-ENC:arrayType="xsd:string[4]"<s-gensym9
      SOAP-ENC:arrayType="xsd:string[4]" xsi:type="SOAP-ENC:Array"><col1 xs
      i:type="xsd:string">a</col1><col2 xsi:type="xsd:string">b</col2><col3
      xsi:type="

      (Is the inclusion of the ~C a bug, or is this some part of the SOAP
      spec I haven't seen ?)

      If I return the array fully qualified with Java types (and provide
      the appropriate mappings in the client), I end up with the following
      error from the Java client:

      Unable to retrieve PropertyDescriptor for property 'col1' of
      class 'class java.util.Hashtable'.

      I may be going about this in completely the wrong way, but if anybody
      would be able to point me in the right direction it would be much
      appreciated.
    • dfg778
      I have managed to get this to work by using the Apache-SOAP VectorSerializer rather than the generic BeanSerializer (for anyone who s interested the relevant
      Message 2 of 2 , Mar 11, 2003
      • 0 Attachment
        I have managed to get this to work by using the Apache-SOAP
        VectorSerializer rather than the generic BeanSerializer (for anyone
        who's interested the relevant code for the server and the client are
        below), however I still can't just return a reference to the Perl
        list-of-list as it produces the ~C in the array type. Is there any
        way to suppress this ?

        The code that I got to work is below:

        SOAP-Lite server class (Transport wraparound not shown) :

        package Demo ;
        use Data::Dumper ;

        sub hi {

        my $output = SOAP::Data->name('String_1' => "Hello from Matthew's
        test SOAP method");
        return $output ;

        }

        sub getLoL {

        my @LoL = ( [qw(a b c d)], [qw(d e f g)]) ;
        my @SOAPLoL ;
        foreach $row (@LoL) {
        my (@SOAProw, $i) ;
        foreach $col (@{$row}) {
        $col = SOAP::Data->name('item')->type('string')->value($col) ;
        push @SOAProw,$col ;
        }
        push @SOAPLoL,SOAP::Data->name("row")->type('Array')->value
        (\@SOAProw) ;
        }
        my $output = SOAP::Data->name('LoL')->type('Array')->value
        (\@SOAPLoL) ;
        #my $output = SOAP::Data->name('LoL' => \@LoL)->type('Array') ;
        #my $output = \@LoL ;
        return $output ;
        }

        1 ;

        Java client (snipped):

        Call call = new Call ();
        SOAPMappingRegistry smr = new SOAPMappingRegistry();
        BeanSerializer beanSer = new BeanSerializer();
        VectorSerializer vecSer = new VectorSerializer() ;
        HashtableSerializer hashSer = new HashtableSerializer() ;

        // Map the types.
        System.out.println("Encoding is " + Constants.NS_URI_SOAP_ENC) ;
        smr.mapTypes(Constants.NS_URI_SOAP_ENC,
        new QName("urn:Demo", "Vector"),
        v.getClass(), vecSer, vecSer);
        smr.mapTypes(Constants.NS_URI_SOAP_ENC,
        new QName("urn:Demo", "Array"),
        v.getClass(), vecSer, vecSer);
        smr.mapTypes(Constants.NS_URI_SOAP_ENC,
        new QName("urn:Demo", "Hashtable"),
        h.getClass(), hashSer, hashSer);
        smr.mapTypes(Constants.NS_URI_SOAP_ENC,
        new QName("urn:Demo", "Map"),
        m.getClass(), hashSer, hashSer);
        smr.mapTypes(Constants.NS_URI_SOAP_ENC,
        new QName
        ("http://www.w3.org/1999/XMLSchema", "String"),
        s.getClass(), beanSer, beanSer);
        call.setSOAPMappingRegistry(smr);
        call.setTargetObjectURI ("urn:Demo");
        call.setMethodName ("getLoL");
        call.setEncodingStyleURI(encodingStyleURI);

        resp = call.invoke(url,"") ;
        if (resp.generatedFault ()) {
        Fault fault = resp.getFault ();
        System.err.println("Generated fault: " + fault);
        System.exit(2) ;
        }
        else {
        System.out.println("Class of respomse value = " +
        resp.getReturnValue ().getClass().getName()) ;
        Parameter result = resp.getReturnValue ();
        Vector value = (Vector)result.getValue() ;
        System.out.println("Class of return value = " +
        value.getClass().getName()) ;
        System.out.println("Response from server = " + value) ;
        }
      Your message has been successfully submitted and would be delivered to recipients shortly.