首页 > 解决方案 > Spring 集成 XPathMessageSplitter + HeadEnricher

问题描述

我目前正在使用 Spring-Integration 和 JavaConfig 并使用 IntegrationFlows。我正在阅读一个 xml 文件,它看起来像:

<?xml version="1.0" encoding="utf-8"?>
<languages>
    <language name='de'>
        <translations>
            <translation key='Aktien' value='Aktien'/>
            <translation key='Andere' value='Andere'/>
        </translation>
    </language>
    <language name='en'>
        <translations>
            <translation key='Aktien' value='Stock'/>
            <translation key='Andere' value='Others'/>
        </translation>
    </language>
</languages>

我的配置目前看起来像:

@Bean
public IntegrationFlow translationFileReadingFlow() throws IOException {
    return IntegrationFlows
            .from(pollableFileSource(), e -> e.poller(Pollers.fixedDelay(MAX_VALUE)))
            .split(translationFileSplitter())
            .channel("processFileChannel")
            .logAndReply();
}

@Bean
@SubscribeMapping(value = "processFileChannel")
public IntegrationFlow applicationShutDown() {
    return IntegrationFlows
            .from("processFileChannel")
            .resequence()
            .handle(new ShutdownService())
            .get();
}

private AbstractMessageSplitter translationFileSplitter() {
    XPathMessageSplitter splitter = new XPathMessageSplitter("/languages/*");
    return splitter; 
}

我想按语言拆分 xml(到目前为止有效),但我还想将语言的信息添加到消息的标题中。信息在 xml 中<language name='de'>。我可以XPathMessageSplitter直接用 解决它还是需要它XPathHeaderEnricher,如果是的话它会如何工作?

先感谢您

标签: xpathspring-integrationheader-enricher

解决方案


不针对主题:

我不确定:

@Bean
@SubscribeMapping(value = "processFileChannel")
public IntegrationFlow applicationShutDown() {

是正确的代码。@SubscribeMapping用于基于 POJO 的方法映射。你绝对不能映射一个IntegrationFlow. 如果您仍然需要从这样的 调用流@SubscribeMapping,则需要考虑引入一个@MessagingGateway接口来启动流并从该 POJO 方法调用。

您确实不能通过拆分器添加标题。这不是它的责任。

如果您需要从 .xml 中的 XML 填充标头payload,您肯定需要查看XPathHeaderEnricher. 在你的情况下,它可能是这样的:

@Bean
public XPathHeaderEnricher xPathHeaderEnricher() {
    Map<String, XPathExpressionEvaluatingHeaderValueMessageProcessor> expressionMap =
            Collections.singletonMap("language",
                    new XPathExpressionEvaluatingHeaderValueMessageProcessor("/language/@name"));
    return new XPathHeaderEnricher(expressionMap);
}

并在提到之后使用.split()

.split(translationFileSplitter())
.handle(xPathHeaderEnricher())

不过,通过 SpEL 还有另一种方法: https ://docs.spring.io/spring-integration/docs/5.2.0.RELEASE/reference/html/spel.html#spel-functions

.enrichHeaders((headers) -> 
             headers.headerExpression("language", "#xpath(payload, '/language/@name')"))

推荐阅读