Как создать Java-объект из 'anyType', возвращенного из сервиса, используя JAXB? - PullRequest
18 голосов
/ 31 января 2012

Веб-сервис возвращает объект, определенный WSDL:

<s:complexType mixed="true"><s:sequence><s:any/></s:sequence></s:complexType>

Когда я распечатываю информацию о классе этого объекта, он выглядит как:

class com.sun.org.apache.xerces.internal.dom.ElementNSImpl

НоМне нужно демонтировать этот объект как объект следующего класса:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = {
        "info",
        "availability",
        "rateDetails",
        "reservation",
        "cancellation",
        "error" }) 
@XmlRootElement(name = "ArnResponse") 
public class ArnResponse { }

Я знаю, что ответ правильный, так как я знаю, как маршалировать XML этого объекта:

Marshaller m = jc.createMarshaller();
m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
m.marshal(rootResponse, System.out);

Какойвыводит на печать:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:SubmitRequestDocResponse xmlns:ns2="http://tripauthority.com/hotel">
    <ns2:SubmitRequestDocResult>
        <!-- below is the object I'm trying to unmarshall -->
        <ArnResponse>
            <Info />
            <Availability>
                <!-- etc--> 
             </Availability>
        </ArnResponse>
    </ns2:SubmitRequestDocResult>
</ns2:SubmitRequestDocResponse>

Как я могу превратить объект ElementNSImpl, который я вижу, в объект ArnResponse, который, как я знаю, представляет?

Кроме того, я работаю на AppEngineгде доступ к файлам ограничен.

Спасибо за любую помощь

Обновление :

Я добавил аннотацию @XmlAnyElement(lax=true), например, так:

  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name = "", propOrder = {
      "content"
  })
  @XmlSeeAlso(ArnResponse.class)
  public static class SubmitRequestDocResult {

    @XmlMixed
    @XmlAnyElement(lax = true)
    protected List<Object> content;

Но это не имеет значения.

Это как-то связано с тем, что контент является List?

Вот код, в котором я пытаюсь получить доступ к контенту после получения его с сервера:

List list = rootResponse.getSubmitRequestDocResult().getContent();

for (Object o : list) {
  ArnResponse response = (ArnResponse) o;
  System.out.println(response);
}

Который имеет выход:

31 января 2012 г. 10:04:14 com.districthp.core.server.ws.alliance.AllianceApi getRates SEVERE: com.sun.org.apache.xerces.internal.dom.ElementNSImpl нельзя привести к com.districthp.core.server.ws.alliance.response.ArnResponse

Ответ:

Ответ Axtavt сделал свое дело.Это сработало:

Object content = ((List)result.getContent()).get(0);
JAXBContext context = JAXBContext.newInstance(ArnResponse.class);
Unmarshaller um = context.createUnmarshaller();
ArnResponse response = (ArnResponse)um.unmarshal((Node)content);
System.out.println("response: " + response);

Ответы [ 3 ]

19 голосов
/ 31 января 2012

Вы можете передать этот объект Unmarshaller.unmarshal(Node), он должен быть в состоянии демонтировать его.

5 голосов
/ 31 января 2012

Вы можете использовать @XmlAnyElement(lax=true).Это преобразует XML с известными корневыми элементами (@XmlRootElement или @XmlElementDecl) в объекты домена.Для примера см .:

2 голосов
/ 31 января 2012

Из того, что я обнаружил при работе с XML, anyType может представлять любой объект, поэтому ближайшая вещь, на которую вы можете отобразить его, - java.lang.Object.(Помимо того факта, что anyType технически может быть дырой в безопасности, позволяющей кому-то вводить что-либо, включая вредоносный бинарный файл, в это место, и ничто не остановит его, поскольку ваша схема это позволяет.)

Вы лучшеотключить, чтобы изменить схему, чтобы разрешить сопоставление с вашим пользовательским объектом.Это чище как с точки зрения программирования, так и с точки зрения потребления и безопасности.

Пока вы этого не сделаете, я бы рекомендовал хранить тип в качестве атрибута вашего элемента.Возможно, вам придется написать собственный код, чтобы потом преобразовать anyType обратно в этот объект, но, по крайней мере, вы знаете его тип.

Мои два цента основаны на моем опыте (в основном в областиинтеграция).

...