2016-05-05 7 views
1

Ich möchte Objekt in XML marshallen.Kann den Typ als XML-Element nicht zuordnen, da die @ XmlRootElement-Annotation fehlt.

schlägt jedoch fehl, es mit Ausnahme:

javax.xml.bind.MarshalException 
- with linked exception: 
[com.sun.istack.SAXException2: unable to marshal type "FreightOfferDetail" as an element because it is missing an @XmlRootElement annotation] 
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:331) 
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:257) 
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:96) 
    at com.wktransportservices.fx.test.util.jaxb.xmltransformer.ObjectTransformer.toXML(ObjectTransformer.java:27) 
    at com.wktransportservices.fx.test.sampler.webservice.connect.FreightOfferToConnectFreight.runTest(FreightOfferToConnectFreight.java:59) 
    at org.apache.jmeter.protocol.java.sampler.JavaSampler.sample(JavaSampler.java:191) 
    at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:429) 
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:257) 
    at java.lang.Thread.run(Thread.java:662) 
Caused by: com.sun.istack.SAXException2: unable to marshal type "FreightOfferDetail" as an element because it is missing an @XmlRootElement annotation 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:244) 
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:303) 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:490) 
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:328) 

In der Tat, diese Anmerkung vorhanden ist (für Eltern und geliefert Klasse):

@XmlRootElement(name = "Freight_Offer") 
@XmlAccessorType(XmlAccessType.FIELD) 
@JsonIgnoreProperties(ignoreUnknown = true) 
@JsonInclude(JsonInclude.Include.NON_EMPTY) 
public class FreightOffer { 
    @JsonIgnore 
    @XmlTransient 
    private String freightId; 
    private String id; 

    private String externalSystemId; 

    private AddressLocation pickUp; 

    private AddressLocation delivery; 

    private FreightDescription freightDescription; 

    private ListContacts contacts; 

    private Customer customer; 

    private ListSla slas; 

    private String pushId; 

    private CompanyProfile company; 

    private Route route; 

    private String href; 

    private Lifecycle lifecycle; 

    private Visibility visibility; 

    private Boolean unfoldedVXMatching; 
    // getters/setters 

Kinderklasse:

@XmlAccessorType(XmlAccessType.PROPERTY) 
public class FreightOfferDetail extends FreightOffer { 

    private List<Contact> contact; 

    @XmlElement(name = "contacts") 
    @JsonProperty("contacts") 
    public List<Contact> getContact() { 
     return contact; 
    } 

    public void setContact(List<Contact> contact) { 
     this.contact = contact; 
    } 

Es versagt genau bei dieser Methode toXML():

public class ObjectTransformer<T> implements Transformer<T> { 

    protected final JAXBContext context; 
    protected final Marshaller marshaller; 

    protected final int okStatusCode = 200; 
    protected final String okSubErrorCode = "OK"; 

    public ObjectTransformer(JAXBContext context) throws JAXBException { 
     this.context = context; 
     marshaller = context.createMarshaller(); 
     marshaller.setProperty("jaxb.encoding", "UTF-8"); 
     marshaller.setProperty("jaxb.formatted.output", Boolean.TRUE); 
    } 

    public String toXML(T object) throws JAXBException { 
     StringWriter writer = new StringWriter(); 
     marshaller.marshal(object, writer); 
     String xmlOffer = writer.toString(); 
     return xmlOffer; 
    } 

Es sollte funktionieren, aber es sollte nicht.

Ich konnte hier nicht finden, was fehlt oder falsch ist.

UPDATE:

Hier Schnipsel aus Test:

public SampleResult runTest(JavaSamplerContext context) { 
    AbstractSamplerResults results = new XMLSamplerResults(new SampleResult()); 
    results.startAndPauseSampler(); 

    if (failureCause != null) { 
     results.setExceptionFailure("FAILED TO INSTANTIATE connectTransformer", failureCause); 
    } else { 
     FreightOfferDTO offer = null; 
     FreightOffer freightOffer = null; 
     try { 
      results.resumeSampler();    

      RouteInfo routeDTO = SamplerUtils.getRandomRouteFromRepo(context.getIntParameter(ROUTES_TOUSE_KEY)); 

      offer = FreightProvider.createRandomFreight(routeDTO, createUserWithLoginOnly(context)); 

      freightOffer = connectTransformer.fromDTO(offer); 
      String xmlOfferString = connectTransformer.toXML(freightOffer); // <- it fails here. 

Ich nehme das Datum aus CSV Datei und Konvertierung in DTO Objekt. Diese Methode gibt mir FreightOfferDetail.

Hier Ausschnitt aus dieser Methode ist:

public FreightOfferDetail freightFromDTO(FreightOfferDTO freightDTO, boolean fullFormat){ 
    FreightOfferDetail freight = new FreightOfferDetail(); 

    freight.setFreightId(freightDTO.getIds().getAtosId()); 
    freight.setId(freightDTO.getIds().getFxId()); 
    // ... 

Wie Objekt in XML-Datei in diesem Fall Marschall?

Antwort

3

Beachten Sie, dass die Fehlermeldung über FreightOfferDetail, nicht FreightOffer spricht.

Basierend darauf würde ich erwarten, dass irgendwo (außerhalb des angegebenen Codes) ein Detail angefordert wird.

Wenn Sie das tun können, wollen (mit JAXB?) Müssen Sie auch diese Klasse zu annotieren mit der XmlRootElement Anmerkung.

+0

ich Ihren Vorschlag versucht. Ergebnis ist das gleiche - 'javax.xml.bind.MarshalException - mit verknüpfter Ausnahme: [com.sun.istack.SAXException2 ...' –

+0

Konnte Sie die gesamte Stack-Trace enthalten? Der Ausnahmetyp sagt nicht viel ohne die zugehörige Ausnahmebedingungsnachricht aus. Und der tatsächliche Marshalling-Aufruf würde helfen, ihn einzugrenzen (d. H. Welche Art von Objekt wird tatsächlich gemarshallt?). –

+0

Sehen Sie sich die Frage an. Es enthält genau diese Ausnahme. –

2
public String toXML(T object) throws JAXBException { 
    StringWriter stringWriter = new StringWriter(); 

    JAXBContext jaxbContext = JAXBContext.newInstance(T.class); 
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

    // format the XML output 
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

    QName qName = new QName("com.yourModel.t", "object"); 
    JAXBElement<T> root = new JAXBElement<Bbb>(qName, T.class, object); 

    jaxbMarshaller.marshal(root, stringWriter); 

    String result = stringWriter.toString(); 
    LOGGER.info(result); 
    return result; 
} 

Hier ist der Artikel, den ich benutze, wenn ich/Abstellungs ohne @XmlRootElement zu Marschall haben: http://www.source4code.info/2013/07/jaxb-marshal-unmarshal-with-missing.html

Alles Gute Hoffnung, es hilft :)

0

Sie die Object Klasse verwenden können, um Workaround für die Klassen, die nicht über das @ XmlRootElement verfügen. ObjectFactory hat Methoden überladen.

Methode: 1 Es tut einfache Erstellung des Objekts und

Methode: 2 Es wird das Objekt mit @JAXBElement umwickeln.

immer Methode zu verwenden: 2 javax.xml.bind.MarshalException zu vermeiden - mit Ausnahme verknüpft fehlt eine @XmlRootElement Anmerkung

Methode: 1

public GetCountry createGetCountry() { 
     return new GetCountry(); 
    } 

Methode: 2

@XmlElementDecl(namespace = "my/name/space", name = "getCountry") 
public JAXBElement<GetCountry> createGetCountry(GetCountry value) { 
     return new JAXBElement<GetCountry>(_GetCountry_QNAME, GetCountry.class, null, value); 
    } 

Weitere Informationen folgen Sie diesem stackoverflow-question

Hope this hilfreich sein ...

Verwandte Themen