2012-01-31 7 views
14

serwis internetowy wraca obiekt zdefiniowany przez WSDL być:Jak utworzyć obiekt java z "anyType" zwrócony z usługi przy użyciu JAXB?

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

Kiedy wydrukować informacje o klasie tego obiektu, to pojawia się jako:

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

Ale muszę wycofać ten obiekt jako obiekt poniższej klasy:

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

wiem, że odpowiedź jest poprawna, ponieważ wiem, jak XML Marszałkowskiego tego obiektu:

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

Który wypisuje:

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

Jak mogę obrócić obiekt ElementNSImpl widzę do obiektu ArnResponse wiem, że to oznacza?

Dodatkowo używam AppEngine, gdzie dostęp do plików jest ograniczony.

Dzięki za wszelką pomoc

aktualizacji:

Dodałem @XmlAnyElement(lax=true) adnotacji, tak jak poniżej:

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

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

Ale to nie robi żadnej różnicy.

Czy ma to coś wspólnego z tym, że treść jest List?

Oto kod gdzie usiłuję dostępu do treści po otrzymaniu go z powrotem z serwera:

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

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

który ma wyjście:

31 stycznia 2012 10:04: 14 AM com.districthp.core.server.ws.alliance.AllianceApi getRATE SEVERE: com.sun.org.apache.xerces.internal.dom.ElementNSImpl nie można przesłać na adres com.districthp.core.server.ws. alliance.response.ArnResponse

Odpowiedź: Odpowiedź

axtavt za załatwiło sprawę. To działało:

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); 
+0

Mam kopie wszystkich schematów dla obiektów odpowiedzi i WSDL, jeśli pomaga to wiedzieć. – Cuga

+4

Należy zauważyć, że użyty tutaj 'Node' to' org.w3c.dom.Node'. –

Odpowiedz

14

Możesz przekazać ten obiekt do Unmarshaller.unmarshal(Node), powinien on być w stanie go unmarshal.

+0

Hej, to działało. Dzięki wielkie! – Cuga

1

Z tego, co ja z pracy z XML znaleziono anyType może reprezentować dowolny obiekt, więc najbliższa rzecz można mapować go z powrotem jest java.lang.Object. (Poza tym fakt, że anyType może być technicznie dziurą bezpieczeństwa, pozwalającą komuś wstrzyknąć cokolwiek, w tym złośliwemu binariowi, i nic nie zatrzyma go, ponieważ pozwala na to twój schemat.)

Najlepiej jest zmienić schemat, aby umożliwić mapowanie do niestandardowego obiektu. Jest to czystsze zarówno z punktu widzenia programowania, perspektywy konsumpcji, jak i perspektywy bezpieczeństwa.

Oczekując, że nie możesz tego zrobić, poleciłbym przechowywanie tego typu jako atrybutu Twojego elementu. Może zaistnieć potrzeba napisania niestandardowego kodu, który pomoże ci przekonwertować obiekt anyType z powrotem na ten obiekt, ale przynajmniej znasz jego typ.

Moje dwa centy oparte na moim doświadczeniu (głównie w zakresie integracji).

+1

Tak, gdybym mógł, nie użyłbym 'anyType', ale integrujemy się z czyimś schematem, więc utknęliśmy z tym. – Cuga

4

Można użyć @XmlAnyElement(lax=true). Spowoduje to konwersję XML ze znanymi elementami root (@XmlRootElement lub @XmlElementDecl) do obiektów domeny. Na przykład patrz:

+1

Sprawdziłem, ale adnotacja już tam była. Proszę spojrzeć na moje zaktualizowane pytanie. Jeszcze raz dziękuję za pomoc. Natknąłem się na Twojego bloga przed Tobą i na inne twoje odpowiedzi. Twoja praca już bardzo mi pomogła. – Cuga

+0

Dzięki, rozwiązałam mój problem! –

Powiązane problemy