PDA

View Full Version : XPathSingleChannelRouter fails to convert DOMSource to Node



turnrob
Oct 6th, 2009, 07:52 AM
Hello,

I am coding a POC for the Spring Integration project.
I am calling a WS with XML payload (String and Document tried) on my server which is implementing a simpleGateway



<ws:inbound-gateway id="simpleGateway"
request-channel="inputChannel"/>


Then I am trying to use the simpleRouter to route the messages into channels



<si-xml:xpath-router id="aRouter" input-channel="inputChannel" multi-channel="false">
<si-xml:xpath-expression expression="/aRequest/someVal/anotherVal"/>
</si-xml:xpath-router>


this is producing the following error :


DEBUG: org.springframework.integration.xml.router.XPathSi ngleChannelRouter - org.springframework.integration.xml.router.XPathSi ngleChannelRouter@e2b9e5 received message: [Payload=javax.xml.transform.dom.DOMSource@1386751][Headers={springintegration_id=8c6c39e8-3ff5-4759-9499-41fee0a9b67d, springintegration_timestamp=1254832382109, springintegration_replyChannel=org.springframework .integration.channel.MessageChannelTemplate$Tempor aryReplyChannel@72edc, springintegration_errorChannel=org.springframework .integration.channel.MessageChannelTemplate$Tempor aryReplyChannel@72edc}]
DEBUG: org.springframework.ws.soap.server.SoapMessageDisp atcher - Endpoint invocation resulted in exception - responding with Fault
org.springframework.integration.core.MessagingExce ption: unsupported payload type [javax.xml.transform.dom.DOMSource]
at org.springframework.integration.xml.DefaultXmlPayl oadConverter.convertToDocument(DefaultXmlPayloadCo nverter.java:66)
at org.springframework.integration.xml.DefaultXmlPayl oadConverter.convertToNode(DefaultXmlPayloadConver ter.java:73)
at org.springframework.integration.xml.router.XPathSi ngleChannelRouter.getChannelIndicatorList(XPathSin gleChannelRouter.java:81)
at org.springframework.integration.router.AbstractCha nnelNameResolvingMessageRouter.determineTargetChan nels(AbstractChannelNameResolvingMessageRouter.jav a:110)
at org.springframework.integration.router.AbstractMes sageRouter.handleMessageInternal(AbstractMessageRo uter.java:72)
at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:59)
at org.springframework.integration.dispatcher.Unicast ingDispatcher.doDispatch(UnicastingDispatcher.java :103)
at org.springframework.integration.dispatcher.Unicast ingDispatcher.dispatch(UnicastingDispatcher.java:9 0)
at org.springframework.integration.channel.AbstractSu bscribableChannel.doSend(AbstractSubscribableChann el.java:43)


I believe the DOMSource should be used and the getNode() method called to get the Node object. Is this a bug? or am I missing a step.

thanks
Rob

iwein
Oct 7th, 2009, 08:45 AM
At the moment Spring Integration doesn't support Source as a payload for the xml support. You can do something yourself quite easily, but from a framework point of view it is not smart to support things that can be linked to an InputStream.

Of course if you have arguments against this policy we'd be very glad to hear them.

turnrob
Oct 7th, 2009, 09:02 AM
Thanks Iwen, Sounds like a sound reason, however I was just linking up XML
through a WS,

I assumed that after bringing the XML into the si world I would then be able to use the XPATH routing.

I did code a converter to call the DOMSource.getNode(), which seemed to work, although the XPATH query always return a null/empty string, which maybe because the source document was SOAP based??

JonasPartner
Oct 7th, 2009, 03:01 PM
The XPath routers use the DefaultXmlPayloadConverter which as Iwein says does not support sources however for the case where we are converting to a Node it seems so trivial that we should. I have created INT-835 (http://jira.springframework.org/browse/INT-835)

JonasPartner
Oct 7th, 2009, 03:24 PM
As to why you are getting nulls, namespaces? Your example Xpath expression assumes everything is in the default namespace. Is that really the case?

You might want to take a look at the reference docs on how to configure XML namespaces for the XPath support http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html#xpath-namespace-support.


Jonas

turnrob
Oct 9th, 2009, 03:20 AM
Just to confirm that the following solution / workaround did work.

My Null XPATH resposes were because I thought the XML payload root should start with single slash / but there must be some other root in play (from WS)



<!-- Expects a channel for each value of order type to exist
second attempt when above causing DOMSource issue, so used my own converter -->
<bean id="singleChannelRoutingEndpoint"
class="org.springframework.integration.endpoint.EventDriv enConsumer">
<constructor-arg>
<bean class="org.springframework.integration.xml.router.XPathSi ngleChannelRouter">
<constructor-arg value="//theNs:aXMLRootRequest/theNs:some/theNs:stuff" />
<constructor-arg ref="theNamespaceMap" />
<property name="converter" ref="domHomeMadeConverter"/>
</bean>
</constructor-arg>
<constructor-arg ref="inputChannel" />
</bean>


The converter just extends DefaultXmlPayloadConverter and performs the following

public Node convertToNode(Object object) {
if (object instanceof DOMSource){
Node node = ((DOMSource)object).getNode();
return node;
}
return super.convertToNode(object);
}

JonasPartner
Oct 9th, 2009, 06:23 AM
Glad you worked out the Xpath expression issue.

This issue with DOMSource is now fixed in head and will be part of 2.0 M1 release.

Jonas