You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-user@axis.apache.org by James Hilling <jh...@yahoo.com> on 2008/03/14 16:22:51 UTC

echo example with arrays / wsdl generated code not quite right

Hello,

I wonder if anyone can help with a problem with a simple array "echo" example, which sends/receives arrays of strings.  I got the WSDL file from axis2-1.3/samples/wsdl/Axis2SampleDocLit.wsdl, and I have used wsdl2c to generate the source like this...  (I can post the wsdl file but I would guess everyone already has it..)

I generated the client code from the wsdl:
wsdl2c -u -ap -d adb -o "D:\_Dev\Axis2c_test\echoSample_client" -uri "D:\_Dev\Axis2c_test\Axis2SampleDocLit.wsdl"

.. and generated the server code from the wsdl:
wsdl2c -ss -sd -ssi -u -ap -d adb  -o "D:\_Dev\Axis2c_test\echoSample_server" -uri "D:\_Dev\Axis2c_test\Axis2SampleDocLit.wsdl"

I then created client program that used the following function to create an array of strings to send to the server.  I created this from scratch as I couldn't find an example to copy from, so this could be wrong and the source of all the problems.   (The SOAP message that gets sent looks plausible though - see below).

int Send_Array(const axutil_env_t *env, axis2_stub_t *stub)
{
    adb_echoStringArrayParam_t *array_param = NULL;
    adb_ArrayOfstring_literal_t *array_of_strings;

    axutil_array_list_t *xx;

    array_param = adb_echoStringArrayParam_create(env);

    array_of_strings = adb_ArrayOfstring_literal_create(env);
    xx = axutil_array_list_create(env, 10);

    axutil_array_list_add(xx, env, "hello");
    axutil_array_list_add(xx, env, "goodbye");

    adb_ArrayOfstring_literal_set_string(array_of_strings, env, xx);

    adb_echoStringArrayParam_set_echoStringArrayParam(array_param, env, array_of_strings);

    axis2_stub_Axis2SampleDocLitService_echoStringArray(stub, env, array_param);

    return 0;
}

This is the SOAP message that gets sent (reformatted for ease of viewing):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/>
    <soapenv:Body>
        <ns1:echoStringArrayParam xmlns:ns1="http://userguide.axis2.apache.org/xsd">
            <ns1:string>hello</ns1:string>
            <ns1:string>goodbye</ns1:string>
        </ns1:echoStringArrayParam>
    </soapenv:Body>
</soapenv:Envelope>

The problem is manifested at the server end in the echoStringArrayParam_deserialize() function when the message is received.  The code snippet where it goes wrong is shown below (from the generated adb_echoStringArrayParam.c)

    /**
     * because elements are not ordered we should surf all the sibling to pick the right one
     */
    for ( current_node = first_node; current_node != NULL;
             current_node = axiom_node_get_next_sibling( current_node, env))
    {
        current_element = axiom_node_get_data_element( current_node, env);
        qname = axiom_element_get_qname( current_element, env, current_node);
        element_qname = axutil_qname_create( env, "echoStringArrayParam", "http://userguide.axis2.apache.org/xsd", "ns1");
        
        printf("Have '%s'\n",   axutil_qname_to_string(element_qname, env));
        printf("Have '%s'\n\n", axutil_qname_to_string(qname, env));
        
        /* Above debug prints print:
        Have 'echoStringArrayParam|http://userguide.axis2.apache.org/xsd|ns1'
        Have 'string|http://userguide.axis2.apache.org/xsd|ns1'
        */
        
        if ( axutil_qname_equals( element_qname, env, qname))
        {
           /** found the requried element */
           break;
        }
    }
    
    
    /* ***** THE PROBLEM - No element found, current_node == NULL  **** */
    
    if ( current_node != NULL)
     :
     :
 
 
So it looks like there is a mismatch of the types that the deserialize function is expecting. 

I managed to get it to work by setting "has_parent" in adb_echoStringArrayParam_serialize():


    // HACK turn this flag on to add the info req'd to make the test in echoStringArrayParam_deserialize pass
    has_parent = TRUE;

    start_input_str = "<ns1:echoStringArrayParam>";
    start_input_str_len = axutil_strlen(start_input_str);
    end_input_str = "</ns1:echoStringArrayParam>";
    end_input_str_len = axutil_strlen(end_input_str);

        if(has_parent)
            axutil_stream_write(stream, env, start_input_str, start_input_str_len);
        adb_ArrayOfstring_literal_serialize( _echoStringArrayParam->attrib_echoStringArrayParam, env, current_node, AXIS2_TRUE);
        if(has_parent)
            axutil_stream_write(stream, env, end_input_str, end_input_str_len);

And it then works. The SOAP message sent this time looks like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/>
<soapenv:Body>
    <ns1:echoStringArrayParam xmlns:ns1="http://userguide.axis2.apache.org/xsd">
        <ns1:echoStringArrayParam>
            <ns1:string>hello</ns1:string>
            <ns1:string>goodbye</ns1:string>
        </ns1:echoStringArrayParam>
    </ns1:echoStringArrayParam>
</soapenv:Body></soapenv:Envelope>/

But I am assuming that something more fundamental must be wrong, as having to hack the machine generated code to make it work sounds alarm bells to me!

Any ideas?  Alternatively if someone could point me to an example of sending arrays / complex data types, with generated code from WSDL I should be able to work out what the difference is.

Regards, James.





      ____________________________________________________________________________________
Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 


---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org