4 replies Latest Post - ‏2011-10-27T14:54:20Z by amra1
9 Posts

Pinned topic RPG WebService Client : Complex type Array ?

‏2011-01-07T06:36:37Z |

I have a situation where I need to send a Complex type Array object which is inside another Complex object to the WebService. I generated the C modules using wsdl2ws & wrote the RPG interface accordingly.

The call function was successes. The String of the first complex object is printed but not the data of array object. Here is the AXIS log printed and it seems there is something wrong in sending AddressDTO[].

Can someone please explain me to how to pass Complex type Array object to C stub to WebService?

C function for Array :

int Axis_Serialize_ArrayOfAddressDTO2(ArrayOfAddressDTO2* param, AXISCHANDLE pSZ, AxiscBool bArray)

RPG Code :

* h * D* Pointer needed to point AXIS stub DPayWS            S               *   D* Prototype to get stub handle (always needed 

for AXIS client) DgetStub          PR              *   EXTPROC(
'get_ClientSRV2_stub') D pEndPoint                       *   Value  Options(*String)   D* Prototype to get rid of stub DdestroyStub      PR                  EXTPROC(
'destroy_ClientSRV2_stub') D pPayWS                          *   Value D   D* Prototype to invoke DShowClient       PR              *   EXTPROC(
'showClient') D pPayWS                          *   Value D pInput                          *   Value     D  FreeClientDTO  PR                  EXTPROC(
'Axis_Delete_ClientDTO2') d  I_PtrResult                    *   Value d  I_PtrSize                     5i 0 Value     D ClientDTO       DS D pClientCode                     * D pClientName                     * d pAddressArray                   * * D AddressDTO      DS                  Qualified  Dim(2) D tRoad                         10a D tTown                         10a d tCity                         10a * *-------------------------------------------------------------------- * Miscellaneous declarations. *-------------------------------------------------------------------- D pRtnMSG         S               * * *   dtClientCode      s             10a   Inz(
'Y5003Z') dtClientName      s             25a   Inz(
'Jhon K')     D OResult         S             25A *   /FREE   
//  the return is a handle that will be used to the real WebService invocation PayWS  = getStub(
'');   Monitor;   
// invoke WebService, pass stub  and ClientDTO 
// returns pointer to string   AddressDTO(1).tRoad =  
'Road1'; AddressDTO(1).tTown =  
'Town1'; AddressDTO(1).tCity =  
'City1';   AddressDTO(2).tRoad =  
'Road2'; AddressDTO(2).tTown =  
'Town2'; AddressDTO(2).tCity =  
'City2';   pClientCode         =  %addr(tClientCode    ); pClientName         =  %addr(tClientName    ); pAddressArray       =  %addr(AddressDTO     );   pRtnMSG    =  showClient(PayWS  : %Addr(ClientDTO) );   Monitor;   
// Prepare output string depending on what was returned. 

if (pRtnMSG   *NULL);   OResult         = %str(pRtnMSG      );   dsply OResult         ;   

else; dsply 
'**no data**'; endif;   On-Error; dsply 
'**WebService Error**'; Endmon; On-Error; dsply 
'**WebService Error**'; Endmon; 
// Clean up FreeClientDTO( %Addr(ClientDTO) :0); destroyStub(PayWS); *inlr = *on; /END-FREE

AXIS Log : (This doesn't have Address data which means there is a error on passing AddressDTO to the WebService.. )

<ns1:showClient xmlns:ns1=
""> <clnt><clientCode>Y5003Y    </clientCode> <clientName>Jhon K                   </clientName> <address></address></clnt> </ns1:showClient> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Please give me an idea..

Updated on 2011-10-27T14:54:20Z at 2011-10-27T14:54:20Z by amra1
  • dm400
    9 Posts

    Re: RPG WebService Client : Complex type Array ?

    ‏2011-01-07T06:43:02Z  in response to dm400
    This is how ClientDTO2 & AddressDTO2 looks like..
    as you can see below, ClientDTO2 have a array of AddressDTO2..
    That is where i couldn't understand how to do in RPG side.. I tried assign a dataStructure array but not success..

    class ClientDTO2 
    private String ClientCode; 
    private String ClientName; 
    private AddressDTO2[] Address; 
    void setClientCode(String clientCode) 
    { ClientCode = clientCode; 
    public String getClientCode() 
    return ClientCode; 
    void setClientName(String clientName) 
    { ClientName = clientName; 
    public String getClientName() 
    return ClientName; 
    void setAddress(AddressDTO2[] address) 
    { Address = address; 
    public AddressDTO2[] getAddress() 
    return Address; 

    class AddressDTO2 
    private String Road; 
    private String City; 
    private String Town; 
    void setTown(String town) 
    { Town = town; 
    public String getTown() 
    return Town; 
    void setCity(String city) 
    { City = city; 
    public String getCity() 
    return City; 
    void setRoad(String road) 
    { Road = road; 
    public String getRoad() 
    return Road; 
  • amra1
    44 Posts

    Re: RPG WebService Client : Complex type Array ?

    ‏2011-01-07T17:01:55Z  in response to dm400
    You have to match C structures to RPG structures.

    So for C struct

    typedef struct AddressDTO2Tag {
    xsdc__string town;
    xsdc__string city;
    xsdc__string road;
    } AddressDTO2;

    You need to have corresponding RPG structure

    D AddressDTO2 DS align qualified dim(2)
    D pTown *
    D pCity *
    D pRoad *

    You will also need a C array to hold this...

    D CArray S * DIM(2)

    For the C struct

    typedef struct AddressDTO2_ArrayTag {
    struct AddressDTO2Tag ** m_Array;
    int m_Size;
    } AddressDTO2_Array;

    The corresponding RPG struct:

    D AddressDTO2_Array...
    D DS align qualified
    D pArray *
    D m_size 10i 0
    D m_Type 10i 0

    Then the C struct

    typedef struct ArrayOfAddressDTO2Tag {
    AddressDTO2_Array* AddressDTO2_Ref;
    } ArrayOfAddressDTO2;

    will need to be mapped to

    D ArrayOfAddressDTO2...
    D DS align qualified
    D pArray *
    and finally C struct

    typedef struct ClientDTO2Tag {
    xsdc__string clientCode;
    xsdc__string clientName;
    ArrayOfAddressDTO2* address;
    } ClientDTO2;


    D ClientDTO2...
    D DS align qualified
    D pClientCode *
    D pClientName *
    D pAddress *


    Then you set fields as follows (just showing array stuff):

    CArray(1) = %addr(AddressDTO2(1));
    CArray(2) = %addr(AddressDTO2(2));

    AddressDTO2_Array.m_Type = 31; // user type
    AddressDTO2_Array.m_Size = 2; // array size
    AddressDTO2_Array.m_Array = %addr(CArray);

    ArrayOfAddressDTO2.pArray = %addr(AddressDTO2_Array);

    ClientDTO2.pAddress = %addr(ArrayOfAddressDTO2);

    Also, when setting string data you should add the null terminator. for example:

    AddressDTO(1).tRoad = 'Road1' + X'00';

    Finally, we just release wsdl2rpg that you may want to take a look at that makes things much simpler. PTFs are:

    SI42234 V5R4M0
    SI42236 V6R1M0
    SI42235 V7R1M0

    Read cover-letter carefully.
  • dm400
    9 Posts

    Re: RPG WebService Client : Complex type Array ?

    ‏2011-01-10T10:35:58Z  in response to dm400
    Thank you so much for pointing me in the right direction
    But I have a one more things to clear it out..

    When I’m execute the cleaning process
    FreeClientDTO( %Addr(ClientDTO2) :0);

    my dspjoblog shows

    The requested heap space operation is invalid. The pointer parameter passed to free or realloc is not valid.

    But if I omitted cleaning procedure, everything looks ok in the joblog
    What’s wrong in cleaning process??
    Thanks again for all of your help!
    • amra1
      44 Posts

      Re: RPG WebService Client : Complex type Array ?

      ‏2011-10-27T14:54:20Z  in response to dm400
      You should be passing the pointer returned by the web service operation, which i think is pRtnMSG.