2012-01-31 19 views
14

Un servicio web devuelve un objeto definido por el WSDL sea:¿Cómo crear un objeto java desde 'anyType' devuelto desde el servicio usando JAXB?

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

Cuando imprimo información de clase de este objeto, lo hará como:

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

pero necesito Resolver referencia este objeto como un objeto de la clase siguiente:

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

sé que la respuesta es correcta, ya que sé cómo Marshall XML de este objeto:

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

que imprime:

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

¿Cómo puedo convertir el objeto ElementNSImpl que estoy viendo en el objeto ArnResponse Sé que representa?

Además, estoy ejecutando en App Engine, donde el acceso a archivos está restringido.

Gracias por cualquier ayuda

actualización:

que he añadido la anotación @XmlAnyElement(lax=true), así:

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

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

Pero eso no hace ninguna diferencia.

¿Esto tiene algo que ver con el hecho de que el contenido es List?

Aquí es donde el código que estoy tratando de acceder al contenido después de conseguir de nuevo desde el servidor:

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

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

que tiene la salida:

31 Ene, 2012 10:04: 14 AM com.districthp.core.server.ws.alliance.AllianceApi getRates SEVERE: com.sun.org.apache.xerces.internal.dom.ElementNSImpl no se puede convertir a com.districthp.core.server.ws. aliance.response.ArnResponse

respuesta: Respuesta

de axtavt hizo el truco. Esto funcionó:

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

que tienen copias de todos los esquemas para los objetos de respuesta y el WSDL, si ayuda a saber que. – Cuga

+4

Tenga en cuenta que el 'Nodo' utilizado aquí es' org.w3c.dom.Node'. –

Respuesta

14

se puede pasar a ese objeto Unmarshaller.unmarshal(Node), debe ser capaz de deserializar ella.

+0

Oye, eso funcionó. ¡Muchas gracias! – Cuga

1

De lo que he encontrado con la utilización de XML, anyType podría representar cualquier objeto, por lo que lo más cercano que se puede asignar de nuevo a es java.lang.Object. (Además, el hecho de que anyType podría ser técnicamente un agujero de seguridad, permitiendo que alguien inserte cualquier cosa, incluido un binario malicioso en ese punto, y nada lo detendrá, ya que su esquema lo permite.)

Usted es el mejor de cambiar el esquema para permitir una asignación a su objeto personalizado. Esto es más limpio tanto desde una perspectiva de programación, una perspectiva de consumo y una perspectiva de seguridad.

A la espera de que no se puede hacer eso, recomendaría almacenar el tipo como un atributo de su elemento. Es posible que deba escribir un código personalizado para ayudarlo a convertir el anyType a ese objeto, pero al menos ya conoce su tipo.

Mis dos centavos con sede fuera de mi experiencia (sobre todo en el ámbito de la integración).

+1

Sí, si pudiera, no usaría 'anyType', pero nos estamos integrando con el esquema de otra persona, por lo que estamos atascados. – Cuga

4

Puede utilizar @XmlAnyElement(lax=true). Esto convertirá XML con elementos raíz conocidos (@XmlRootElement o @XmlElementDecl) en objetos de dominio. Para ver un ejemplo:

+1

Lo revisé pero la anotación ya estaba allí. Por favor, eche un vistazo a mi pregunta actualizada. Gracias de nuevo por su ayuda, y he encontrado su blog antes y sus otras respuestas aquí en SO. Tu trabajo ya me ha estado ayudando mucho. – Cuga

+0

¡Gracias, resolvió mi problema! –

Cuestiones relacionadas