I am currently using Spring-Integration with JavaConfig and using IntegrationFlows. I am reading in a xml-file which looks like:
<?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>
My Configuration currently looks like:
@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;
}
I would like to split the xml by language (what works so far), BUT I would like to add also the information of the languages into the header of the message. The information are in the xml <language name='de'>
. Can I solve it with the XPathMessageSplitter
directly or do I need the XPathHeaderEnricher
, if yes how would it work?
Thank you in advance
Not to the subject:
I'm not sure that:
@Bean
@SubscribeMapping(value = "processFileChannel")
public IntegrationFlow applicationShutDown() {
Is correct code. The @SubscribeMapping
is for a POJO-based method mapping. You definitely can't map an IntegrationFlow
. If you still need to call a flow from such a @SubscribeMapping
, you need to consider to introduce a @MessagingGateway
interface for starting the flow and calling from that POJO-method.
You indeed cannot add headers via splitter. It is just not its responsibility.
If you need to populate a header from an XML in the payload
, you definitely need to take a look into XPathHeaderEnricher
. In your case it could be like this:
@Bean
public XPathHeaderEnricher xPathHeaderEnricher() {
Map<String, XPathExpressionEvaluatingHeaderValueMessageProcessor> expressionMap =
Collections.singletonMap("language",
new XPathExpressionEvaluatingHeaderValueMessageProcessor("/language/@name"));
return new XPathHeaderEnricher(expressionMap);
}
and use after that mentioned .split()
:
.split(translationFileSplitter())
.handle(xPathHeaderEnricher())
There is another way via SpEL, though: 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')"))