2010-02-15 2 views
8

Ich versuche, ein Objekt zu marshallen, das ein Objekt als eines seiner Felder hat.JAXB Marshalling Objekte mit java.lang.Object Feld

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

Die dataObject- kann eine von vielen verschiedenen unbekannt Typen sein, so dass jeder irgendwo Angabe ist nicht nur unpraktisch, sondern unmöglich. Wenn ich versuche, das Objekt zu marshallen, sagt es, dass die Klasse dem Kontext nicht bekannt ist.

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

String ti_m = JAXBMarshall.marshall(ti); 

"MockProcessData noch irgendeine seiner Super-Klasse ist in diesem Zusammenhang bekannt." ist was ich bekomme.

Gibt es einen Weg um diesen Fehler?

+0

Was Sie zu serialisiert MockProcessData versuchen? d.h. was ist die gewünschte Darstellung? – mtpettyp

+0

Als JAXB-Benutzer zum ersten Mal habe ich genau das gleiche Problem, das versucht, einen Objektbaum zu marshalieren, der von Grund auf neu erstellt wurde, d. H. Nicht von einer kompilierten XSD erstellt wurde. Eigentlich möchte ich es umgekehrt machen und das Schema aus den Klassen generieren, sobald ich den Code funktioniere. Ich habe versucht, mein Objekt in einem JAXBElement wie beschrieben zu verpacken, und ich habe genau die gleiche "Foobar ist nicht in diesem Zusammenhang bekannt" Nachricht wie zuvor, also bin ich nicht weiter vorne. –

+0

Hey Dasmotiu - Ich habe die Annotation @XMLSeeAlso eingeschlossen und alle Klassen zur Verfügung gestellt, mit denen ich versuchen konnte, das Objekt zu entpacken. Zum Beispiel: @XmlSeeAlso ({ StringType.class, DecimalType.class, NumericType.class, BooleanType.class, StructType.class, ListType.class, DateType.class, SpatialType.class }) öffentliche abstrakte Klasse FieldType { – jcovert

Antwort

6

JAXB kann kein altes Objekt marshallen, da es nicht weiß wie. Zum Beispiel würde es nicht wissen, welcher Elementname verwendet werden soll.

Wenn Sie mit dieser Art von Platzhalter umgehen müssen, besteht die einzige Lösung darin, die Objekte in ein -Objekt zu verpacken, das genügend Informationen enthält, damit JAXB zu XML marshallen kann.

Probieren Sie etwas wie:

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

Sieht gut aus, aber ich habe zwei Fragen dazu. Erstens, der Elementname - es ist mir nicht ganz klar, wofür es verwendet wird, aber ich nehme an, "dataObject" wäre ausreichend? Und zweitens ist JAXBElement ein unformatierter Typ, und der Compiler warnt mich, dass er parametrisiert werden sollte. Ich weiß, eine Warnung ist eine Warnung und kein Fehler, aber da ich in unbekanntem Gebiet bin, scheint es eine gute Idee zu sein, mehr zu erfahren. Ich bin mir nicht sicher, was ich mit beiden parametrisieren würde, da es sich um 'Objekte' handelt. Vielen Dank! – jcovert

+0

@jcovert: Der Elementname und der Namespace können beliebig sein, also wäre 'dataObject' in Ordnung. Wie für die Generika, verwenden Sie einfach 'JaxbElement ', es ist nur eine Kompilation Sache, JAXB kümmert sich nicht zur Laufzeit. – skaffman

+1

Es hat ein paar Minuten gedauert, bis es funktionierte, aber das ist in der Tat eine ausgezeichnete Lösung. Eine kleine Änderung (für alle anderen, die das gleiche Problem haben): 'ti.setDataObject (jaxbElement)' sollte 'ti.setDataObject (jaxbElement.getValue())' Nochmals vielen Dank für die Hilfe! – jcovert

0

Methode:

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) { 

     } 
} 

Modell:

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