Search code examples
jaxb2-maven-pluginspring-oxm

Jaxb Binding with List returned in web service response


I am developing a jax-ws client, I am trying to handle an ArrayList returned as a response, but i had always empty list.

Returned list is NOT empty, I am sure that WebService provider is returning data in that list, I checked that using SoapUI.

there is generated client related files:

 @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ArrayOfFact", propOrder = {
    "item"
})
public class ArrayOfFact {

    protected List<Fact> item;
 public List<Fact> getItem() {
        if (item == null) {
            item = new ArrayList<Fact>();
        }
        return this.item;
    }

}

ArrayOfFacts class generated by wsimport it's the same class generated before.

The XML response I receive in SOAPUI :

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <ReleveResponse xmlns="http://www.test.ma/webservices/WSTestServe/">
         <ReleveResult>
            <ConversationId>conId</ConversationId>
            <Status>
               <WSStatus>OK</WSStatus>
               <WSCode>OK</WSCode>
               <WSMessage>Le traitement s’est bien déroulé!</WSMessage>
            </Status>
            <myReleveInfo>
               <NomCli>El Karkouri youssef</NomCli>
               <NbrImp>7</NbrImp>
               <Facture>
                  <Fact>
                     <RefImp>FACT-124</RefImp>
                     <MntImp>230</MntImp>
                     <LibImp>label 1</LibImp>
                     <FlgPaiObl>1</FlgPaiObl>
                  </Fact>
                  <Fact>
                     <RefImp>FACT-125</RefImp>
                     <MntImp>260</MntImp>
                     <LibImp>label 0</LibImp>
                     <FlgPaiObl>0</FlgPaiObl>
                  </Fact>
                  <Fact>
                     <RefImp>FACT-126</RefImp>
                     <MntImp>360</MntImp>
                     <LibImp>label 2</LibImp>
                     <FlgPaiObl>0</FlgPaiObl>
                  </Fact>
                  <Fact>
                     <RefImp>FACT-127</RefImp>
                     <MntImp>236</MntImp>
                     <LibImp>label 3</LibImp>
                     <FlgPaiObl>0</FlgPaiObl>
                  </Fact>
                  <Fact>
                     <RefImp>FACT-128</RefImp>
                     <MntImp>2310</MntImp>
                     <LibImp>label 4</LibImp>
                     <FlgPaiObl>1</FlgPaiObl>
                  </Fact>
                  <Fact>
                     <RefImp>FACT-129</RefImp>
                     <MntImp>2450</MntImp>
                     <LibImp>label 0</LibImp>
                     <FlgPaiObl>1</FlgPaiObl>
                  </Fact>
                  <Fact>
                     <RefImp>FACT-167</RefImp>
                     <MntImp>2380</MntImp>
                     <LibImp>label 1125</LibImp>
                     <FlgPaiObl>0</FlgPaiObl>
                  </Fact>
               </Facture>
            </myReleveInfo>
         </ReleveResult>
      </ReleveResponse>
   </soapenv:Body>
</soapenv:Envelope>

The JSON response I receive whwn I test the jax-ws client :

{
"status": "OK",
"language": "en",
"data": {
    "conversationId": {
        "name": "{http://www.test.ma/webservices/WSTestServe/}ConversationId",
        "declaredType": "java.lang.String",
        "scope": "ma.comp.company.client.testserv.AbstractBean",
        "value": "conId",
        "nil": false,
        "globalScope": false,
        "typeSubstituted": false
    },
    "status": {
        "name": "{http://www.test.ma/webservices/WSTestServe/}Status",
        "declaredType": "ma.comp.company.client.testserv.StatusBeanOut",
        "scope": "ma.comp.company.client.testserv.AbstractBeanOutOfReleveInfo",
        "value": {
            "wsstatus": "OK",
            "wscode": "OK",
            "wsmessage": "Le traitement s’est bien déroulé!"
        },
        "nil": false,
        "globalScope": false,
        "typeSubstituted": false
    },
    "myReleveInfo": {
        "nomCli": {
            "name": "{http://www.test.ma/webservices/WSTestServe/}NomCli",
            "declaredType": "java.lang.String",
            "scope": "ma.comp.company.client.testserv.ReleveInfo",
            "value": "El Karkouri youssef",
            "nil": false,
            "globalScope": false,
            "typeSubstituted": false
        },
        "nbrImp": {
            "name": "{http://www.test.ma/webservices/WSTestServe/}NbrImp",
            "declaredType": "java.lang.String",
            "scope": "ma.comp.company.client.testserv.ReleveInfo",
            "value": "7",
            "nil": false,
            "globalScope": false,
            "typeSubstituted": false
        },
        "facture": {
            "name": "{http://www.test.ma/webservices/WSTestServe/}Facture",
            "declaredType": "ma.comp.company.client.testserv.ArrayOfFact",
            "scope": "ma.comp.company.client.testserv.ReleveInfo",
            "value": {
                "item": []
            },
            "nil": false,
            "globalScope": false,
            "typeSubstituted": false
        }
    }
},
"message": null

}

Fact class:

    @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Fact", propOrder = {
    "refImp",
    "mntImp",
    "libImp",
    "flgPaiObl"
})
public class Fact {

    @XmlElementRef(name = "RefImp", namespace = "http://www.test.ma/webservices/WSTesServe/", type = JAXBElement.class, required = false)
    protected JAXBElement<String> refImp;
    @XmlElementRef(name = "MntImp", namespace = "http://www.test.ma/webservices/WSTesServe/", type = JAXBElement.class, required = false)
    protected JAXBElement<String> mntImp;
    @XmlElementRef(name = "LibImp", namespace = "http://www.test.ma/webservices/WSTesServe/", type = JAXBElement.class, required = false)
    protected JAXBElement<String> libImp;
    @XmlElementRef(name = "FlgPaiObl", namespace = "http://www.test.ma/webservices/WSTesServe/", type = JAXBElement.class, required = false)
    protected JAXBElement<String> flgPaiObl;

    // Getters and Setters

}

Solution

  • I fixed that by adding an xml element declaration in class ObjectFactory generated by wsimport

    @XmlElementDecl(namespace = "http://www.test.ma/webservices/WSTestServe/", name = "Fact", scope = ArrayOfFact.class)
    public JAXBElement<Fact> createArrayOfFactItem(Fact value) {
        return new JAXBElement<Fact>(_ReleveInfoFact_QNAME, Fact.class, ArrayOfFact.class, value);
    }
    

    And the list of items should be annotated by :

    @XmlElementRef(name = "Fact", namespace = "http://www.test.ma/webservices/WSTestServe/", type = JAXBElement.class, required = false)
    protected List<Fact> item;