[英]Spring: OXM error when unmarshalling XML string (castor)
我正在做Spring Integration项目。 我想通过解组转换器将XML字符串发布到一个通道并在其他通道中接收Java对象。
在我的Spring配置中,我正在使用这些通道和bean:
<!-- 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" />
我在单元测试中尝试这个,所以我有自动连接的通道使用:
@Autowired @Qualifier("channels.pubsub.inXml")
MessageChannel inXmlChannel;
@Autowired @Qualifier("channels.fromXmlChannel")
MessageChannel fromXmlChannel;
我希望解组的交易类是非常简单的POJO:
class Trade {
String id;
String direction;
// getters, setters, constructors
}
这是我的JUnit测试方法,但我在第3行得到例外:
@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());
}
最后是这里的堆栈跟踪:
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
要解决此问题,您需要指定要解析的类。 CastorMarshaller有两个属性targetClasses,它们是一个Objects和targetPackages数组,它们是一个Strings数组,你可以验证这个类的来源。
下面的代码将解决您的问题没有映射文件。
<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>
如果要解析的类仍然未知,则必须验证xml文件格式。
示例:
Java类
public class MyUser {
// class attributs
private String firstNameField;
private String lastNameField;
// class methods
//......
}
xml文件
<?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>
请参阅CastorMarshaller的java文档。 将<property name =“targerClass”value =“foo.Trade”/>添加到编组器。
您必须在castor配置文件中指定或作为unmarshaller配置的一部分指定您的trade
标记应映射到您的Trade
类,这似乎是这里的问题。
您应该可以使用CastorMarshaller本身直接执行此操作:
<bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller">
<property name="targetClasses>
<list>
<value>Trade.class</value>
</list>
</property>
</bean>
使用下面的代码它将解决这个问题。
<bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller">
<property name="targetClasses" value="Trade">
</property>
贸易应该是你的名字。
使用此属性:
marshaller.setUseXSITypeAtRoot(true);
然后在xml中你会看到属性xsi:type = in root element with exact class。 Unmarshaller将在此之后工作。
试试这个示例格式,要注意的主要是 - unMarshaller.setClass(com.hello.test.order.cw.bind.Message.class); 这将在非默认包中找到该类,默认情况下unmarshaller期望该类在默认包中。
/**
*
* @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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.