Discussions

XML & Web services: WebSphere web service array deserialization issue

  1. I am currently developing Web Services with RAD and J2EE 1.3, packaging the Web Services in an EAR and deploying this EAR onto WebSphere Application Server v5.1. My client is a J2EE application running on RAD. I am currently having an issue with the Web Service correctly deserializing arrays passed into the operation by a client.The Web Service only seems to deserialize the last array element passed by the client.

    I have a complex type with the following definition:
       <complexType name="SomePersonBO">
        <complexContent>
         <extension base="tns2:SomeBaseEntityBO">
          <sequence>
           <element maxOccurs="unbounded" name="aliases" nillable="true" type="xsd:string"/>
           <element maxOccurs="unbounded" name="attributes" nillable="true" type="tns2:SomeAttribute"/>
          </sequence>
         </extension>
        </complexContent>
       </complexType>


    There is an operation with the following definition:

          <wsdl:operation name="searchPersons">
             <wsdl:input message="impl:searchPersonsRequest" name="searchPersonsRequest"/>
             <wsdl:output message="impl:searchPersonsResponse" name="searchPersonsResponse"/>
             <wsdl:fault message="impl:SomeException" name="SomeException"/>
          </wsdl:operation>

       <wsdl:message name="searchPersonsRequest">
          <wsdl:part element="impl:searchPersons" name="parameters"/>
       </wsdl:message>
       <wsdl:message name="searchPersonsResponse">
          <wsdl:part element="impl:searchPersonsResponse" name="parameters"/>
       </wsdl:message>

       <element name="searchPersons">
        <complexType>
         <sequence>
          <element name="orgContainerBO" nillable="true" type="tns2:SomeOrgContainerBO"/>
          <element name="personBO" nillable="true" type="tns2:SomePersonBO"/>
         </sequence>
        </complexType>
       </element>
       <element name="searchPersonsResponse">
        <complexType>
         <sequence>
          <element maxOccurs="unbounded" minOccurs="0" name="searchPersonsReturn" type="tns2:SomePersonBO"/>
         </sequence>
        </complexType>
       </element>

    This basically involves the Some performing a search with some selection criteria, and then returning an array of SomePersonBO objects to the Some client. When an array is passed from Some -> client, this seems to work fine.

    However, I have another operation with the following definition:

          <wsdl:operation name="modifyPerson">
             <wsdl:input message="impl:modifyPersonRequest" name="modifyPersonRequest"/>
             <wsdl:output message="impl:modifyPersonResponse" name="modifyPersonResponse"/>
             <wsdl:fault message="impl:SomeException" name="SomeException"/>
          </wsdl:operation>


       <wsdl:message name="modifyPersonRequest">
          <wsdl:part element="impl:modifyPerson" name="parameters"/>
       </wsdl:message>
       <wsdl:message name="modifyPersonResponse">
          <wsdl:part element="impl:modifyPersonResponse" name="parameters"/>
       </wsdl:message>

       <element name="modifyPerson">
        <complexType>
         <sequence>
          <element name="orgContainerBO" nillable="true" type="tns2:SomeOrgContainerBO"/>
          <element name="personBO" nillable="true" type="tns2:SomePersonBO"/>
         </sequence>
        </complexType>
       </element>
       <element name="modifyPersonResponse">
        <complexType>
         <sequence>
          <element maxOccurs="unbounded" minOccurs="0" name="modifyPersonReturn" type="tns2:SomeRequestStatus"/>
         </sequence>
        </complexType>
       </element>

    To modify a person, I need to set an array of attributes. However, when the Some client sets the attributes array in the SomePersonBO parameter to pass into the operation, only the last attribute is serialized by the Web Service. So passing arrays from client -> Some does not work. I have used WebSphere's tcpmon tool to view the soap message on the server and it contains all the attributes passed by the client, which means that the client is correctly deserializing:

    <p250:modifyPerson...>
      <p250:orgContainerBO>
        ...
      </p250:orgContainerBO>
      <p250:personBO>
    <p941:attributes ...>
    ...
    </p941:attributes ...>
    <p941:attributes ...>
    ...
    </p941:attributes ...>
    <p941:attributes ...>
    ...
    </p941:attributes ...>
    <p941:attributes ...>
    ...
    </p941:attributes ...>
      </p250:personBO>
    </p250:modifyPerson>

    Does anyone have any idea why the Web Service does not deserialize the array correctly?
  2. I am currently developing Web Services with RAD and J2EE 1.3, packaging the Web Services in an EAR and deploying this EAR onto WebSphere Application Server v5.1. My client is a J2EE application running on RAD. I am currently having an issue with the Web Service correctly deserializing arrays passed into the operation by a client.The Web Service only seems to deserialize the last array element passed by the client.

    I have a complex type with the following definition:
       <complexType name="WSPersonBO">
        <complexContent>
         <extension base="tns2:WSBaseEntityBO">
          <sequence>
           <element maxOccurs="unbounded" name="aliases" nillable="true" type="xsd:string"/>
           <element maxOccurs="unbounded" name="attributes" nillable="true" type="tns2:WSAttribute"/>
          </sequence>
         </extension>
        </complexContent>
       </complexType>


    There is an operation with the following definition:

          <wsdl:operation name="searchPersons">
             <wsdl:input message="impl:searchPersonsRequest" name="searchPersonsRequest"/>
             <wsdl:output message="impl:searchPersonsResponse" name="searchPersonsResponse"/>
             <wsdl:fault message="impl:WSException" name="WSException"/>
          </wsdl:operation>

       <wsdl:message name="searchPersonsRequest">
          <wsdl:part element="impl:searchPersons" name="parameters"/>
       </wsdl:message>
       <wsdl:message name="searchPersonsResponse">
          <wsdl:part element="impl:searchPersonsResponse" name="parameters"/>
       </wsdl:message>

       <element name="searchPersons">
        <complexType>
         <sequence>
          <element name="orgContainerBO" nillable="true" type="tns2:WSOrgContainerBO"/>
          <element name="personBO" nillable="true" type="tns2:WSPersonBO"/>
         </sequence>
        </complexType>
       </element>
       <element name="searchPersonsResponse">
        <complexType>
         <sequence>
          <element maxOccurs="unbounded" minOccurs="0" name="searchPersonsReturn" type="tns2:WSPersonBO"/>
         </sequence>
        </complexType>
       </element>

    This basically involves the WebService performing a search with some selection criteria, and then returning an array of WSPersonBO objects to the WebService client. When an array is passed from WebService -> client, this seems to work fine.

    However, I have another operation with the following definition:

          <wsdl:operation name="modifyPerson">
             <wsdl:input message="impl:modifyPersonRequest" name="modifyPersonRequest"/>
             <wsdl:output message="impl:modifyPersonResponse" name="modifyPersonResponse"/>
             <wsdl:fault message="impl:WSException" name="WSException"/>
          </wsdl:operation>


       <wsdl:message name="modifyPersonRequest">
          <wsdl:part element="impl:modifyPerson" name="parameters"/>
       </wsdl:message>
       <wsdl:message name="modifyPersonResponse">
          <wsdl:part element="impl:modifyPersonResponse" name="parameters"/>
       </wsdl:message>

       <element name="modifyPerson">
        <complexType>
         <sequence>
          <element name="orgContainerBO" nillable="true" type="tns2:WSOrgContainerBO"/>
          <element name="personBO" nillable="true" type="tns2:WSPersonBO"/>
         </sequence>
        </complexType>
       </element>
       <element name="modifyPersonResponse">
        <complexType>
         <sequence>
          <element maxOccurs="unbounded" minOccurs="0" name="modifyPersonReturn" type="tns2:WSRequestStatus"/>
         </sequence>
        </complexType>
       </element>

    To modify a person, I need to set an array of attributes. However, when the WebService client sets the attributes array in the WSPersonBO parameter to pass into the operation, only the last attribute is serialized by the Web Service. So passing arrays from client -> WebService does not work. I have used WebSphere's tcpmon tool to view the soap message on the server and it contains all the attributes passed by the client, which means that the client is correctly deserializing:

    <p250:modifyPerson...>
      <p250:orgContainerBO>
        ...
      </p250:orgContainerBO>
      <p250:personBO>
    <p941:attributes ...>
    ...
    </p941:attributes ...>
    <p941:attributes ...>
    ...
    </p941:attributes ...>
    <p941:attributes ...>
    ...
    </p941:attributes ...>
    <p941:attributes ...>
    ...
    </p941:attributes ...>
      </p250:personBO>
    </p250:modifyPerson>

    Does anyone have any idea why the Web Service does not deserialize the array correctly?
  3. Most probably your Java class corresponding to the xml schema type containing the array type does not have the index based getters and setters. For each array element, index based getter and setter have to be added in the corresponding java class (in addition to the getter and setter that uses array). Assuming ur using an array of strings, the following 2 have to be added public String getXXX(int i) public void setXXX(int i, String xxx) Otherwise deserialization will deserialize only one element in the array (the last element of the array)
  4. Could you be a little bit more specific about it ? I have the same problem.. These are my original array getters and setters: public Data[] getData(){ return Data; } public void setData (Data[] data){ Data = data; } I've tried adding these methods (overload): public Data getData(int i){ return Data[i]; } public void setData (int i, Data data){ Data[i] = data; } But my array is empty when it gets serialized in the webservice.. I get a null pointer exception when i'm trying to access the Data array. Any help would be appreciated
  5. OK, my mistake, it's working now :) Thanks for he tip
  6. Hi all, I´m having the same problems, so I follow the tips and it worked. I´m just worried about if this is some rule about web services and array ? or this is just a WebSphere issue? regards
  7. Hi Everybody. I am very new to the web service. I have created a web service as below.. I am mentioning my java Classes below for your information. [u]CPServices.java[/u] import java.net.HttpURLConnection; import java.net.URL; import java.net.URLDecoder; import org.apache.log4j.Logger; import org.apache.soap.encoding.Hex; import utility.ArrayString; public class CPServices implements Serializable { /** * */ HttpURLConnection _oConn = null; public void smsMo(java.lang.String service_id, java.lang.String source_mobtel, java.lang.String sub_id, java.lang.String keyword, java.lang.String transaction_id, java.lang.String short_code_suffix_ind, java.lang.String short_code_suffix, AdditionalInfo[] array_of_info, SMSContent[] sms_contents) { System.out.println("Control Inside the smsMo()"); } public void mtResp(java.lang.String service_id, java.lang.String source_mobtel, java.lang.String destination_mobtel, java.lang.String delivery_channel, java.lang.String transaction_id, java.lang.String ref_id, int notification_ind, java.lang.String error_code, java.lang.String success_list, java.lang.String error_list) { System.out.println("Control Inside the mtResp()"); } } [u]SMSContent.java[/u] import java.io.Serializable; public class SMSContent implements Serializable { public java.lang.String content; public java.lang.String ucp_data_coding_id; public java.lang.String ucp_msg_class; public java.lang.String ucp_msg_type; public SMSContent() { } public SMSContent(java.lang.String content, java.lang.String ucp_data_coding_id, java.lang.String ucp_msg_class, java.lang.String ucp_msg_type) { this.content = content; this.ucp_data_coding_id = ucp_data_coding_id; this.ucp_msg_class = ucp_msg_class; this.ucp_msg_type = ucp_msg_type; } public java.lang.String getContent() { return content; } public void setContent(java.lang.String content) { this.content = content; } public java.lang.String getUcp_data_coding_id() { return ucp_data_coding_id; } public void setUcp_data_coding_id(java.lang.String ucp_data_coding_id) { this.ucp_data_coding_id = ucp_data_coding_id; } public java.lang.String getUcp_msg_class() { return ucp_msg_class; } public void setUcp_msg_class(java.lang.String ucp_msg_class) { this.ucp_msg_class = ucp_msg_class; } public java.lang.String getUcp_msg_type() { return ucp_msg_type; } public void setUcp_msg_type(java.lang.String ucp_msg_type) { this.ucp_msg_type = ucp_msg_type; } } [u]AdditionalInfo.java[/u] import java.io.Serializable; public class AdditionalInfo implements Serializable { public java.lang.String name; public java.lang.String value; public AdditionalInfo() { } public AdditionalInfo(java.lang.String name, java.lang.String value) { this.name = name; this.value = value; } public java.lang.String getName() { return name; } public void setName(java.lang.String name) { this.name = name; } public java.lang.String getValue() { return value; } public void setValue(java.lang.String value) { this.value = value; } } When i triet to test my Web service.. the mtResp() in the webservice is working fine. But when i tested the smsMo() method it was giving the below error : - - - soapenv:Server.userException org.xml.sax.SAXException: No deserializer for {http://DefaultNamespace}SMSContent - sfjdev I am getting problem in receiving the Array parameters into the Web service.. Can anyone help me regarding this.. I need to complete this work within tomorrow.. Someone please help me to get out of this Bug...