オブジェクトをXMLにマーシャリングしたい。
ただし、例外が発生して失敗します。
_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)
_
実際、この注釈は存在します(親クラスおよび提供されたクラスの場合):
_@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
_
子クラス:
_@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;
}
_
このメソッドで正確に失敗します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;
}
_
動作するはずですが、動作しないはずです。
私はここで何が欠けているか間違っているかを見つけることができませんでした。
UPDATE:
ここにテストからのスニペットがあります:
_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.
_
[〜#〜] csv [〜#〜]ファイルから日付を取得して[〜#〜] dto [〜#〜]オブジェクト。このメソッドは私に戻ります_FreightOfferDetail.
_
このメソッドのスニペットは次のとおりです。
_public FreightOfferDetail freightFromDTO(FreightOfferDTO freightDTO, boolean fullFormat){
FreightOfferDetail freight = new FreightOfferDetail();
freight.setFreightId(freightDTO.getIds().getAtosId());
freight.setId(freightDTO.getIds().getFxId());
// ...
_
この場合、オブジェクトをXMLファイルにマーシャリングする方法
エラーメッセージはFreightOfferDetail
ではなくFreightOffer
に関するものであることに注意してください。
これに基づいて、(提供されたコードの外の)どこかで、ディテールをマーシャリングするように求めていると思います。
あなたがそれを行うことができるようにしたい場合([〜#〜] jaxb [〜#〜]?)を使用してそのクラスにもXmlRootElementアノテーションを付ける必要があります。
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;
}
@XmlRootElementなしでマーシャリング/アンマーシャリングする必要があるときに使用する記事は次のとおりです: http://www.source4code.info/2013/07/jaxb-marshal-unmarshal-with-missing.html
それが役に立てば幸いです:)
ObjectFactoryクラスを使用して、@ XmlRootElementを持たないクラスの回避策をとることができます。 ObjectFactoryにはオーバーロードされたメソッドがあります。
Method:1オブジェクトを簡単に作成し、
メソッド:2@ JAXBElementでオブジェクトをラップします。
常にMethod:2を使用してjavax.xml.bind.MarshalExceptionを回避します-リンクされた例外で@XmlRootElementアノテーションが欠落しています
メソッド:1
public GetCountry createGetCountry() {
return new GetCountry();
}
メソッド:2
@XmlElementDecl(namespace = "my/name/space", name = "getCountry")
public JAXBElement<GetCountry> createGetCountry(GetCountry value) {
return new JAXBElement<GetCountry>(_GetCountry_QNAME, GetCountry.class, null, value);
}
詳細については、これに従ってください stackoverflow-question
これが役に立てば幸い...
Sthを使用して、Apache-cxf maven-pluginでWSDLからJavaオブジェクトを作成する場合。お気に入り:
<plugin>
<groupId>org.Apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
...
</plugin>
自動的に生成されるObjectFactoryがあります。
Java=で例外を構成する場合、この生成されたObjectFactoryを使用して障害を返すことができます。重要な手順は、JAXBElement<YourSoapFault>
例外のgetFaultInfo()メソッドで。
@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);
}
}