简体   繁体   English

无法将类型编组为XML元素,因为缺少@XmlRootElement注释

[英]Unable to marshal type as XML element because @XmlRootElement annotation is missing

I want to marshal object to XML. 我想将对象编组为XML。

However, it fails with exception: 但是,它失败,但有例外:

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 fact, this annotation is present (for parent and delivered class): 实际上,这个注释存在(对于父类和交付类):

@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

Child class: 儿童班:

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

It fails exactly at this method toXML() : 它完全失败了这个方法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;
    }

It should work, but it shouldn't. 它应该工作,但它不应该。

I couldn't find what is missed or wrong here. 我在这里找不到错过或错误的地方。

UPDATE: 更新:

Here is snippet from 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.

I take the date from CSV file and converting to DTO object. 我从CSV文件中取出日期并转换为DTO对象。 This method returns to me FreightOfferDetail. 这个方法返回给我FreightOfferDetail.

Here is snippet from this method: 以下是此方法的代码段:

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

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

How to marshal object to XML file, at this case? 在这种情况下,如何将对象编组为XML文件?

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

Here is the article I use when I have to marshal/unmarshal without @XmlRootElement: http://www.source4code.info/2013/07/jaxb-marshal-unmarshal-with-missing.html 这是我在没有@XmlRootElement的情况下编组/解组时使用的文章: http//www.source4code.info/2013/07/jaxb-marshal-unmarshal-with-missing.html

All the best hope it helps :) 所有最好的希望它有帮助:)

Note that the error message talks about FreightOfferDetail , not FreightOffer . 请注意,错误消息涉及FreightOfferDetail ,而不是FreightOffer

Based on that, I would expect that somewhere (outside the provided code), you're asking a Detail to be marshalled. 基于此,我希望在某个地方(在提供的代码之外),你要求细节被编组。

If you want to be able to do that (with JAXB ?) you need to annotate that class as well with the XmlRootElement annotation. 如果您希望能够这样做(使用JAXB ?),您还需要使用XmlRootElement注释来注释该类。

You can use the ObjectFactory class to workaround for the classes which doesn't have the @XmlRootElement . 您可以使用ObjectFactory类来解决没有@XmlRootElement的类 ObjectFactory has overloaded methods. ObjectFactory有重载方法。

Method:1 It does simple creation of the object and 方法:1它可以简单地创建对象和

Method:2 It will wrap the object with @JAXBElement . 方法:2它将使用@JAXBElement包装对象。

Always to use Method:2 to avoid javax.xml.bind.MarshalException - with linked exception missing an @XmlRootElement annotation 总是使用方法:2来避免javax.xml.bind.MarshalException - 链接异常缺少@XmlRootElement注释

Method:1 制法:1

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

Method:2 方法:2

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

for more information follow this stackoverflow-question 有关更多信息,请参阅此stackoverflow问题

Hope this will be helpful... 希望这会有所帮助......

When creating the Java-Objects from the WSDL with the apache-cxf maven-plugin, using sth. 使用apache-cxf maven-plugin从WSDL创建Java对象时,使用sth。 like: 喜欢:

<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    ...
</plugin> 

There will be a automatically generated ObjectFactory. 将会有一个自动生成的ObjectFactory。

When configuring your Exception in Java you can use this generated ObjectFactory for returning the fault. 在Java中配置Exception时,可以使用此生成的ObjectFactory返回错误。 The important step is to return a JAXBElement<YourSoapFault> in the getFaultInfo() method of your exception. 重要的一步是在异常的JAXBElement<YourSoapFault> ()方法中返回JAXBElement<YourSoapFault>

@WebFault(name = "YourSoapFault",
        targetNamespace = "ns://somenamespace")
public class SomeWebServiceException extends RuntimeException {
    private final YourSoapFault fault;

    public SomeWebServiceException(String message, YourSoapFault fault) {
        super(message);
        this.fault = fault;
    }

    public SomeWebServiceException(String message, YourSoapFault fault, Throwable e) {
        super(message, e);
        this.fault = fault;
    }

    public JAXBElement<YourSoapFault> getFaultInfo() {
        return new ObjectFactory().createYourSoapFault(fault);
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法将类型 [...] 编组为元素,因为它缺少 @XmlRootElement 注释 - unable to marshal type […] as an element because it is missing an @XmlRootElement annotation 无法将类型编组为元素,因为它缺少自动生成的类的 @XmlRootElement 注释 - unable to marshal type as an element because it is missing an @XmlRootElement annotation for auto generated classes JMS消息,由于缺少@XmlRootElement批注,因此无法将类型“ java.lang.String”作为元素封送 - JMS message, unable to marshal type “java.lang.String” as an element because it is missing an @XmlRootElement annotation 无法将类型“java.lang.Integer”编组为元素,因为它缺少 @XmlRootElement 注释 - unable to marshal type "java.lang.Integer" as an element because it is missing an @XmlRootElement annotation 我有@xmlrootelement,但一直收到此异常:无法将类型编组为元素,因为它缺少@XmlRootElement - I have @xmlrootelement , but keep getting this exception: unable to marshal type as an element because it is missing an @XmlRootElement 存在@XmlRootElement批注时,无法封送Java类 - Unable to marshal Java class when @XmlRootElement annotation is present Java:无法封装类型“entities.Person”作为元素因为 - Java : unable to marshal type “entities.Person” as an element because 无法编组类型,用于弹簧控制器的XML输出 - Unable to marshal type, XML output for spring controller 尝试使用JAXB将对象编组为xml文件时,出现“缺少@XmlRootElement批注”错误 - I get the error as “missing an @XmlRootElement annotation” while trying to marshall an object into xml file using JAXB jakarta.xml.bind.annotation.XmlRootElement 是否可用? - is jakarta.xml.bind.annotation.XmlRootElement is available?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM