2010-02-15 18 views
8

Estoy intentando ordenar un objeto que tiene un objeto como uno de sus campos.JAXB Marshalling Objects con el campo java.lang.Object

@XmlRootElement 
public class TaskInstance implements Serializable { 
    ... 
    private Object dataObject; 
    ... 
} 

El dataObject puede ser uno de los muchos diferentes tipos desconocidos, por lo que la especificación de cada uno en algún lugar no sólo es poco práctico, sino imposible. Cuando trato de ordenar el objeto, dice que el contexto no conoce la clase.

MockProcessData mpd = new MockProcessData(); 
TaskInstance ti = new TaskInstance(); 
ti.setDataObject(mpd); 

String ti_m = JAXBMarshall.marshall(ti); 

"MockProcessData ni ninguno de sus super clase se conoce a este contexto." es lo que obtengo

¿Hay alguna forma de evitar este error?

+0

¿Qué estás tratando de serializar MockProcessData a? es decir, ¿cuál es la representación deseada? – mtpettyp

+0

Como primer usuario de JAXB, tengo exactamente el mismo problema al tratar de ordenar un árbol de objetos creado desde cero, es decir, no creado a partir de un XSD compilado. De hecho, quiero hacerlo al revés y generar el esquema de las clases una vez que tenga el código funcionando. Traté de envolver mi objeto en un JAXBElement como se describe, y obtuve exactamente el mismo mensaje "Foobar no se conoce en este contexto" que antes, así que no estoy más adelante. –

+0

Hola Dasmotiu - Terminé incluyendo la anotación @XMLSeeAlso y proporcionando todas las clases que podría tratar de destrabar el objeto. Por ejemplo: @XmlSeeAlso ({ StringType.class, DecimalType.class, NumericType.class, BooleanType.class, StructType.class, ListType.class, DateType.class, SpatialType.class }) clase abstracta pública FieldType { – jcovert

Respuesta

6

JAXB no puede ordenar ningún objeto viejo, ya que no sabe cómo hacerlo. Por ejemplo, no sabría qué nombre de elemento usar.

Si necesita manejar este tipo de comodín, la única solución es envolver los objetos en un objeto JAXBElement, que contiene suficiente información para que JAXB marque como XML.

intentar algo como:

QName elementName = new QName(...); // supply element name here 
JAXBElement jaxbElement = new JAXBElement(elementName, mpd.getClass(), mpd); 
ti.setDataObject(jaxbElement); 
+0

Se ve bien, pero tengo dos preguntas sobre esto. En primer lugar, el nombre del elemento: no está exactamente claro para qué se usa, pero supongo que "dataObject" sería suficiente. Y en segundo lugar, JAXBElement es un tipo sin procesar, y el compilador me advierte que debe ser parametrizado. Sé que una advertencia es una advertencia y no un error, pero como estoy en un territorio desconocido, me parece una buena idea averiguar más. No estoy seguro de con qué lo parametrizaría, ya que estoy tratando con 'Objetos'. ¡Gracias! – jcovert

+0

@jcovert: el nombre del elemento y el espacio de nombres pueden ser lo que quieras, así que sí, 'dataObject' estaría bien. En cuanto a los genéricos, simplemente use 'JaxbElement ', es solo una compilación, a JAXB no le importa en tiempo de ejecución. – skaffman

+1

Me llevó unos minutos hacerlo funcionar, pero de hecho esta es una excelente solución. Un pequeño cambio (para cualquier otra persona que pueda encontrar el mismo problema): 'ti.setDataObject (jaxbElement)' debe ser 'ti.setDataObject (jaxbElement.getValue())' ¡Gracias de nuevo por la ayuda! – jcovert

0

Método:

public String marshallXML(Object object) { 
     JAXBContext context; 
     try { 
      context = JAXBContext.newInstance(object.getClass()); 
      StringWriter writer = new StringWriter(); 
      Marshaller marshaller = context.createMarshaller(); 
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
      marshaller.marshal(object, writer); 
      String stringXML = writer.toString(); 
      return stringXML; 
     } catch (JAXBException e) { 

     } 
} 

Modelo:

import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
@XmlRootElement 
public class Customer { 
    String name; 
    int id; 
    public String getName() { 
     return name; 
    } 
    @XmlElement 
    public void setName(String name) { 
     this.name = name; 
    } 
    public int getId() { 
     return id; 
    } 
    @XmlAttribute 
    public void setId(int id) { 
     this.id = id; 
    } 
}