Полный список элементов не отображается после десериализации строки XML в объект с помощью преобразователя XML Джексона

Моя входная строка XML содержит список записей. Когда я десериализую его в объект с помощью jackson xmlmapper, я вижу только один элемент в списке. Родительские элементы определены в POJO как универсальные объекты.

xml строка (ItemList содержит 3 элемента):

<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:

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;
    }

}

Хотя во входной строке xml есть 3 элемента в ItemList, объект результата содержит только 3-й элемент.

Результат:

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"
          }
        }
      }
    }
  }
}

person Sparkle8    schedule 11.05.2015    source источник


Ответы (1)


Ваш пример не будет работать без объявления фактических типов head и body. Обычный Object приведет к тому, что body будет привязан как Map, а с повторяющимися элементами с тем же именем останется только последний. Основные проблемы заключаются в том, что XML не делает различий между массивами и объектами (в отличие от JSON), и единственный способ устранить разницу - использовать информацию из классов Java. Итак, вам нужно иметь что-то с List или типом массива, чтобы связывать вещи как массивы.

person StaxMan    schedule 11.05.2015
comment
Хм .. Мне нужно было бы изменить подход. JSON - это вход для моего приложения. С помощью Spring web я получаю pojo, а затем конвертирую его в xml для вызова внешнего интерфейса. XML-ответ внешнего интерфейса конвертируется в pojo. Возникла вышеупомянутая проблема с несколькими элементами. Спасибо за быстрый ответ! - person Sparkle8; 11.05.2015
comment
У меня есть XSD для входящего запроса, поэтому решение будет генерировать pojo из xsd (используя cxf), а затем использовать это pojo для сериализации / десериализации xml с помощью XmlMapper. Есть ли другое лучшее решение? - person Sparkle8; 11.05.2015
comment
Я подозреваю, что определение типа в XSD недостаточно полно, чтобы давать реальные типы? Я не знаю, почему он производит только Object. Но без реального типа содержимого десериализовать содержимое невозможно; сериализация может работать. - person StaxMan; 13.05.2015