[英]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.