3

I need help to mapping my Soap Envelope to java Classes, my intention manipulate the results to DB.

I dont't have problems with get my SOAP Envelope or to work With DB, my problems is totaly with JABX and mapping my classes according my SOPA Envoloap.

This is my SOAP:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Header>
      <KD4SoapHeaderV2 xmlns="http://www.ibm.com/KD4Soap">A03ODA1YzhlZDQ2MWQAAQ==</KD4SoapHeaderV2>
   </soap:Header>
   <soap:Body>
      <Response xmlns="http://tempuri.org/">
         <Result xmlns:a="http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <a:Errors />
            <a:Count>329</a:Count>
            <a:Return>SUCCESS</a:Return>
            <a:DashboardDTOs>
               <a:DashboardDTOs>
                  <a:Value>28.58</a:Value>
                  <a:Code>O001</a:Code>
                  <a:Name>Test2</a:Name>
               </a:DashboardDTOs>
               <a:DashboardDTOs>
                  <a:Value>40.22</a:Value>
                  <a:Code>O002</a:Code>
                  <a:Name>Test2</a:Name>
               </a:DashboardDTOs>
               <a:DashboardDTOs>
                  <a:Value>54.11</a:Value>
                  <a:Code>O003</a:Code>
                  <a:Name>Test3</a:Name>
               </a:DashboardDTOs>
            </a:DashboardDTOs>
         </Result>
      </Response>
   </soap:Body>
</soap:Envelope>

This is my the Class with receive the main values (count, return and list of Dashboards DTO):

@XmlRootElement(name = "Response") 
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Response", propOrder = { "Count",  "Return", "DashboardDTOs"})
public class Result {

    @XmlElement(name="Count", required = true)
    private Integer Count;

    @XmlElement(name="Return", required = true)
    private String Return;

    @XmlElement(name = "DashboardDTOs")
    private List<DashboardDTOs> DashboardDTOs;

    ...

This is the second model that receives the DashboardDTO:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "DashboardDTOs", propOrder = {
        "Value",
        "Code",
        "Name"
    })
public class DashboardDTOs {

    @XmlElement(name = "Value")
    private double Value;

    @XmlElement(name = "Code")
    private String Code;

    @XmlElement(name = "Name")
    private String Name;

    ...

And my app try to convert the SOAPEnvelope to a Result but I got error:

Unmarshaller unmarshaller = JAXBContext.newInstance(Result.class).createUnmarshaller();
GetListSummarizedTransactionResultDTO returnValue = (Result)unmarshaller.unmarshal(soapMessagem.getSOAPBody().extractContentAsDocument());



unexpected element (uri:"http://tempuri.org/", local:"Response"). Expected elements are <{}Result>

what I'm doing wrong?

Thans

Leonardo Machado
  • 63
  • 1
  • 3
  • 6

1 Answers1

5

Try this:

First you have your root class, Response

@XmlRootElement(name = "Response", namespace = "http://tempuri.org/")
@XmlAccessorType(XmlAccessType.FIELD)
public class Response {

    @XmlElement(name="Result", namespace = "http://tempuri.org/")
    private Result result;
}

which contains the Result:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Result", propOrder = { "Errors", "Count",  "Return", "DashboardDTOs"})
public class Result {

    @XmlElement(name="Errors", required = true, namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private String Errors;

    @XmlElement(name="Count", required = true, namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private Integer Count;

    @XmlElement(name="Return", required = true, namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private String Return;

    @XmlElement(name = "DashboardDTOs", namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private List<DashboardDTOs> DashboardDTOs;
}

Now it get's a bit "messy" for my taste. Your xml contains an element DashboardDTOs which inside it contains a list of DashboardDTOs and those have value, code, names. So you need to create a DashboardDTOs class like this:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "DashboardDTOs", propOrder = {
        "Value",
        "Code",
        "Name",
        "DashboardDTOs"
})
public class DashboardDTOs {

    @XmlElement(name = "Value", namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private double Value;

    @XmlElement(name = "Code", namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private String Code;

    @XmlElement(name = "Name", namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private String Name;

    @XmlElement(name = "DashboardDTOs", namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private List<DashboardDTOs> DashboardDTOs;
}

These POJOs will allow you to marshal/unmarshal with the specified xml inside the body.

Update to respond to comment:

With the updated xml, the classes would look like:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "DashboardDTOs")
public class DashboardDTOs {

    @XmlElement(name = "DashboardDTO", namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private List<DashboardDTO> dashboardDTO;
}

and:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {
        "value",
        "code",
        "Nnme",
})
public class DashboardDTO {
    @XmlElement(name = "Value", namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private double value;

    @XmlElement(name = "Code", namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private String code;

    @XmlElement(name = "Name", namespace = "http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response")
    private String Nnme;
}

Now using an xml file (for convenience):

<Response xmlns="http://tempuri.org/">
    <Result xmlns:a="http://schemas.datacontract.org/2004/07/PS.SharedWebServices.Response" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:Errors />
        <a:Count>329</a:Count>
        <a:Return>SUCCESS</a:Return>
        <a:DashboardDTOs>
            <a:DashboardDTO>
                <a:Value>28.58</a:Value>
                <a:Code>O001</a:Code>
                <a:Name>Test2</a:Name>
            </a:DashboardDTO>
            <a:DashboardDTO>
                <a:Value>40.22</a:Value>
                <a:Code>O002</a:Code>
                <a:Name>Test2</a:Name>
            </a:DashboardDTO>
            <a:DashboardDTO>
                <a:Value>54.11</a:Value>
                <a:Code>O003</a:Code>
                <a:Name>Test3</a:Name>
            </a:DashboardDTO>
        </a:DashboardDTOs>
    </Result>
</Response>

And trying if the marshaling/unmarshaling works in a simple main:

public static void main(String[] args) {

    try {

        File file = new File("response.xml");
        JAXBContext jaxbContext = JAXBContext.newInstance(Response.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

        Response response = (Response) jaxbUnmarshaller.unmarshal(file);
        System.out.println(response);

    } catch (JAXBException e) {
        e.printStackTrace();
    }

}

works fine for me. Try this in the main and if it works, but then it does not in your application, let me know and we can see what else can be wrong there.

martidis
  • 2,897
  • 1
  • 11
  • 13