2

My input XML string contains a list of entries. When I deserialize it into object using jackson xmlmapper I see only one item in the list is coming. The parent elements have been defined as generic objects in POJO.

xml string (ItemList contains 3 items) :

<msg>
   <head>
      <Client>MyClient</Client>
      <RoutingArea>Test</RoutingArea>
      <ServerId>ABCXYZ123</ServerId>
   </head>
   <body>
      <UserDetailResponse>
         <UserDetail>
            <Customer>
               <CustomerId>1456342711975</CustomerId>
               <BusinessUnit>TEST0000</BusinessUnit>
               <Name>
                  <Salutation>U</Salutation>
                  <First>TROPICAL TAN</First>
               </Name>
               <Privacy>Y</Privacy>
            </Customer>
            <ItemList>
               <Count>3</Count>
               <Item>
                  <ServiceIdentifier>000001</ServiceIdentifier>
                  <BillingIdentifier>000001</BillingIdentifier>
               </Item>
               <Item>
                  <ServiceIdentifier>000002</ServiceIdentifier>
                  <BillingIdentifier>000002</BillingIdentifier>
               </Item>
               <Item>
                  <ServiceIdentifier>000003</ServiceIdentifier>
                  <BillingIdentifier>000003</BillingIdentifier>
               </Item>
            </ItemList>
         </UserDetail>
      </UserDetailResponse>
   </body>
</msg>

Java code:

private final static XmlMapper mapper = new XmlMapper();

public static <T> T getXmlObject(String xml, Class<T> cls) throws IOException {
    return mapper.readValue(xml, cls);
}

public static void main(String[] args) throws Exception {
    String xmlString = "<msg><head><Client>MyClient</Client><RoutingArea>Test</RoutingArea><ServerId>ABCXYZ123</ServerId></head><body><UserDetailResponse><UserDetail><Customer><CustomerId>1456342711975</CustomerId><BusinessUnit>TEST0000</BusinessUnit><Name><Salutation>U</Salutation><First>TROPICAL TAN</First></Name><Privacy>Y</Privacy></Customer><ItemList><Count>3</Count><Item><ServiceIdentifier>000001</ServiceIdentifier><BillingIdentifier>000001</BillingIdentifier></Item><Item><ServiceIdentifier>000002</ServiceIdentifier><BillingIdentifier>000002</BillingIdentifier></Item><Item><ServiceIdentifier>000003</ServiceIdentifier><BillingIdentifier>000003</BillingIdentifier></Item></ItemList></UserDetail></UserDetailResponse></body></msg>";

    JacksonXmlModule jacksonXmlModule = new JacksonXmlModule();
    jacksonXmlModule.setDefaultUseWrapper(false);

    MyResponse myResponse = getXmlObject(xmlString, MyResponse.class);

    System.out.println("XML Object: \n" + myResponse.toString());

    ObjectMapper mapper = new ObjectMapper();
    String str = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(myResponse);
    System.out.println("JSON : \n" + str);

}

POJO:

public class MyResponse {

    private Object head;

    private Object body;

    public Object getHead() {
        return head;
    }

    public void setHead(Object head) {
        this.head = head;
    }

    public Object getBody() {
        return body;
    }

    public void setBody(Object body) {
        this.body = body;
    }

}

Though there are 3 items under ItemList in the input xml string the result object contains only 3rd item.

Result:

JSON : 
{
  "head" : {
    "Client" : "MyClient",
    "RoutingArea" : "Test",
    "ServerId" : "ABCXYZ123"
  },
  "body" : {
    "UserDetailResponse" : {
      "UserDetail" : {
        "Customer" : {
          "CustomerId" : "1456342711975",
          "BusinessUnit" : "TEST0000",
          "Name" : {
            "Salutation" : "U",
            "First" : "TROPICAL TAN"
          },
          "Privacy" : "Y"
        },
        "ItemList" : {
          "Count" : "3",
          "Item" : {
            "ServiceIdentifier" : "000003",
            "BillingIdentifier" : "000003"
          }
        }
      }
    }
  }
}
Sparkle8
  • 225
  • 3
  • 13

1 Answers1

0

Your example will not work without declaring actual types of head and body. Plain Object will cause body to be bound as Map, and with repeated elements of same name, only last one ends up retained. The underlying problems is that XML has no distinction between Arrays and Objects (unlike JSON), and the only way to resolve the difference is with information from Java classes. So you need to have something with List or array type to bind things as arrays.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
  • Hmm.. I would need to change the approach. JSON is the input for my application. With Spring web I am getting pojo then converting it into xml for calling external interface. XML response of external interface being converted into pojo. Ran into above issue with multiple items. Thanks for quick response! – Sparkle8 May 11 '15 at 19:49
  • I have XSD for the incoming request so solution would be generate pojo from xsd(using cxf) and then use that pojo to serialize/deserialize xml using XmlMapper. Any other better solution? – Sparkle8 May 11 '15 at 19:53
  • I suspect that type definition in XSD is not complete enough to give actual types? I don't know why it would only produce `Object`. But without real content type, it will not be possible to deserialize the contents; serialization may work. – StaxMan May 12 '15 at 21:11