【问题标题】:xpath-router doesn't route message with xpath-expressionxpath-router 不使用 xpath-expression 路由消息
【发布时间】:2017-12-23 16:50:35
【问题描述】:

我使用 Spring Integration XML 路由器和xpath-expression

<int:chain input-channel="routerInputChannel">
    <int-xml:xpath-router default-output-channel="routerOutputChannel">
        <int-xml:xpath-expression expression="//actor[1]/text()"/>
        <int-xml:mapping value="Christian Bale" channel="routerBaleChannel"/>
    </int-xml:xpath-router>
</int:chain>

并期望此 XML 字符串作为 SI 消息负载

<root xmlns:foo="http://www.foo.org/" xmlns:bar="http://www.bar.org">
    <actors>
        <actor id="1">Christian Bale</actor>
        <actor id="2">Liam Neeson</actor>
        <actor id="3">Michael Caine</actor>
    </actors>
    <foo:singers>
        <foo:singer id="4">Tom Waits</foo:singer>
        <foo:singer id="5">B.B. King</foo:singer>
        <foo:singer id="6">Ray Charles</foo:singer>
    </foo:singers>
</root>

将发送到routerBaleChannel,但由于某种原因它不起作用。

我在XPath Tester / Evaluator 尝试了消息和XPath 表达式,正如预期的那样,我得到了Christian Bale 字符串。

我调试了org.springframework.integration.xml.router.XPathRouter方法getChannelKeys,发现Jaxp13XPathExpressionFactory方法evaluate内部有问题:执行后原因不明

NodeList nodes = (NodeList) evaluate(node, XPathConstants.NODESET);

nodes.getLength() 返回空列表。

那么我的 XPath 路由器或 XPath 表达式配置有什么问题?

【问题讨论】:

    标签: java spring xpath spring-integration


    【解决方案1】:

    为我工作:

    <int:chain input-channel="inputChannel">
        <int-xml:xpath-router>
            <int-xml:xpath-expression expression="//actor[1]/text()"/>
            <int-xml:mapping value="Christian Bale" channel="routerBaleChannel"/>
        </int-xml:xpath-router>
    </int:chain>
    
    <int:channel id="routerBaleChannel">
        <int:queue/>
    </int:channel>
    

    ...

    @Test
    public void testSO45173221() {
        ClassPathXmlApplicationContext ac =
                new ClassPathXmlApplicationContext("XPathRouterTests-context.xml", this.getClass());
        MessageChannel inputChannel = ac.getBean("inputChannel", MessageChannel.class);
        PollableChannel channelBale = ac.getBean("routerBaleChannel", PollableChannel.class);
        GenericMessage<String> message =
                new GenericMessage<>("<root xmlns:foo=\"http://www.foo.org/\" xmlns:bar=\"http://www.bar.org\">\n" +
                "    <actors>\n" +
                "        <actor id=\"1\">Christian Bale</actor>\n" +
                "        <actor id=\"2\">Liam Neeson</actor>\n" +
                "        <actor id=\"3\">Michael Caine</actor>\n" +
                "    </actors>\n" +
                "    <foo:singers>\n" +
                "        <foo:singer id=\"4\">Tom Waits</foo:singer>\n" +
                "        <foo:singer id=\"5\">B.B. King</foo:singer>\n" +
                "        <foo:singer id=\"6\">Ray Charles</foo:singer>\n" +
                "    </foo:singers>\n" +
                "</root>");
        inputChannel.send(message);
        Message<?> result = channelBale.receive(0);
        assertNotNull(result);
        assertEquals(message.getPayload(), result.getPayload());
        ac.close();
    }
    

    不知道你的情况是怎么回事...

    虽然我使用的是 Java 8,仅供参考。

    【讨论】:

    • 我的路由器定义有什么不同吗?我看不到。
    • 正确,没有。我使用您提供的相同内容,正如您在测试中看到的那样,我发送相同的payload 和字符串。您使用什么 SI 版本?
    • 我使用 Spring 4.3.7.RELEASE 和 SI Java DSL 1.1.4.RELEASE
    • Spring 集成版本,好吗?请问Ja​​va DSL 和这个问题有什么关系?
    • 别担心:我已经以另一种方式实现了所需的功能。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多