Spring: OXM error while parsing XML string (movie)

I am running a Spring Integration project. I would like to publish an XML string in one channel and get a Java object in another channel using unmarshalling transformer.

In my Spring configuration, I use these feeds and beans:

<!-- channel to for publishing XML string --> <int:publish-subscribe-channel id="channels.pubsub.inXml" /> <!-- channel for receiving transformed reply --> <int:channel id="channels.fromXmlChannel"> <int:queue capacity="10" /> </int:channel> <!-- transformer unmarshalling XML to Java object --> <int-xml:unmarshalling-transformer unmarshaller="marshaller" input-channel="channels.pubsub.inXml" output-channel="channels.fromXmlChannel" /> <!-- marshaller bean --> <bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller" /> 

I am trying to use this in unit test, so I have auto-negotiation channels:

 @Autowired @Qualifier("channels.pubsub.inXml") MessageChannel inXmlChannel; @Autowired @Qualifier("channels.fromXmlChannel") MessageChannel fromXmlChannel; 

The trading class I want to unleash is very trivial for POJO:

 class Trade { String id; String direction; // getters, setters, constructors } 

Here is my JUnit test method, but I get an exception in the third line:

  @Test public void testUnmarshallingTransformer() { String xml = "<trade id='ID-01' direction='DIR-PRG' />"; Message<String> message = MessageBuilder.withPayload(xml).build(); inXmlChannel.send(message, TIMEOUT); Message<?> received = ((PollableChannel) fromXmlChannel).receive(TIMEOUT); System.out.println("\n\n" + received.getPayload()); } 

And finally here is stacktrace:

 org.springframework.integration.transformer.MessageTransformationException: failed to transform message at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:44) at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:67) at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:97) at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:105) at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:96) at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:61) at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157) at sk.xorty.transformers.BuiltinTransformersTest.testUnmarshallingTransformer(BuiltinTransformersTest.java:190) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) at org.junit.runner.JUnitCore.run(JUnitCore.java:157) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) Caused by: org.springframework.oxm.UnmarshallingFailureException: Castor unmarshalling exception; nested exception is org.exolab.castor.xml.MarshalException: The class for the root element 'trade' could not be found.{File: [not available]; line: 1; column: 41} at org.springframework.oxm.castor.CastorMarshaller.convertCastorException(CastorMarshaller.java:487) at org.springframework.oxm.castor.CastorMarshaller.unmarshalReader(CastorMarshaller.java:399) at org.springframework.oxm.support.AbstractMarshaller.unmarshalStreamSource(AbstractMarshaller.java:371) at org.springframework.oxm.support.AbstractMarshaller.unmarshal(AbstractMarshaller.java:134) at org.springframework.integration.xml.transformer.UnmarshallingTransformer.transformPayload(UnmarshallingTransformer.java:107) at org.springframework.integration.transformer.AbstractPayloadTransformer.doTransform(AbstractPayloadTransformer.java:33) at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:33) ... 39 more Caused by: org.exolab.castor.xml.MarshalException: The class for the root element 'trade' could not be found.{File: [not available]; line: 1; column: 41} at org.exolab.castor.xml.Unmarshaller.convertSAXExceptionToMarshalException(Unmarshaller.java:866) at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:763) at org.springframework.oxm.castor.CastorMarshaller.unmarshalReader(CastorMarshaller.java:396) ... 44 more Caused by: org.xml.sax.SAXException: The class for the root element 'trade' could not be found. at org.exolab.castor.xml.UnmarshalHandler.processFirstElement(UnmarshalHandler.java:890) at org.exolab.castor.xml.StartElementProcessor.compute(StartElementProcessor.java:103) at org.exolab.castor.xml.UnmarshalHandler.startElementProcessing(UnmarshalHandler.java:811) at org.exolab.castor.xml.UnmarshalHandler.startElement(UnmarshalHandler.java:733) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:506) at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182) at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.emptyElement(XMLDTDValidator.java:766) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1302) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(XMLDocumentScannerImpl.java:1275) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3063) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:881) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:488) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568) at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:751) ... 45 more 
+4
source share
6 answers

To solve this problem, you need to specify your class that you want to parse. CastorMarshaller has two attributes, targetClasses, which is an array of objects and targetPackages, which is an array of strings, which you can check the source of this class.

The code below will solve your problem without a mapping file.

 <bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller"> <property name="targetClasses"> <array> <value>Your class location (ex : com.domain.YourClass)</value> </array> </property> </bean> 

If the parsing class is not yet known, you must confirm your xml file format.

Example:

Java class

 public class MyUser { // class attributs private String firstNameField; private String lastNameField; // class methods //...... } 

xml file

 <?xml version="1.0" encoding="UTF-8"?> <my-user> <first-name-field>firstName</first-name-field> <last-name-field>lastName</last-name-field> </my-user> 
+2
source

See java docs for CastorMarshaller. Add <property name = "targeterClass" value = "foo.Trade" / "> to the marshaller.

+1
source

You must specify either in the Castor configuration file or as part of the unmarshaller configuration that the trade tag should display in your trade class, this seems to be the problem.

You can do this directly using CastorMarshaller itself:

 <bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller"> <property name="targetClasses> <list> <value>Trade.class</value> </list> </property> </bean> 
0
source

Use this code below to solve this problem.

 <bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller"> <property name="targetClasses" value="Trade"> </property> 

Trade must be your name pojo.

0
source

Use this property:

 marshaller.setUseXSITypeAtRoot(true); 

then in xml you will see the xsi: type = attribute in the root element with the exact class. After that, Unmarshaller will work.

0
source

Try this sample format, the main thing to view is unMarshaller.setClass (com.hello.test.order.cw.bind.Message.class); which will find the class in a non-standard package, by default unmarshaller expects the class to be in the default package.

 /** * * @param inType * @param elements * @param orderInXml * @return */ private boolean validateXMLForTargetElements(String inType, List<String> elements,String orderInXml) { try { Unmarshaller unMarshaller = new Unmarshaller(); StringReader stringReader = new StringReader(orderInXml); unMarshaller.setClass(com.hello.test.order.cw.bind.Message.class); System.out.println("The XML After Modification "+orderInXml); com.hello.test.order.cw.bind.Message message = (Message) unMarshaller.unmarshal(stringReader); System.out.println("The Object Message After" + " Converting from XML is "+message); } catch(Exception ex) { ex.printStackTrace(); } return false; } 
0
source

All Articles