Issue
In spring-integration I'm wanting to "update" a list of values that are kept within a message header, using a header-enricher.
In my example, I've created an inline list {'x', 'y'}
and I want to add 'z'
to that list. I haven't found an example of how to do this in SpEL. It seems like it should be a common, trivial thing to do.
<si:header-enricher>
<si:header name="myList" expression="{ 'x', 'y' }" />
</si:header-enricher>
...
<si:header-enricher default-overwrite="true" >
<!-- CLEARLY THIS DOESN'T WORK BUT USING TO DEMONSTRATE THE DESIRED RESULT -->
<si:header name="myList" expression="{ headers.myList, 'z' }" />
</si:header-enricher>
How does one indicate that you want to create a new inline list that is the result of adding a value to an existing list?
In the demonstration code, the outcome would be [ [ 'x', 'y' ], 'z' ]
rather than the desired ['x', 'y', 'z' ]
.
thanks for any pointers
Solution
This uses the Java DSL, but the expressions will work in XML too
@Bean
IntegrationFlow flow() {
return IntegrationFlows.fromSupplier(() -> "foo", e -> e.poller(Pollers.fixedDelay(Duration.ofSeconds(5))))
.enrichHeaders(headers -> headers
.headerExpression("list", "{ 'x', 'y' }"))
.enrichHeaders(headers -> headers
.headerExpression("list", "T(java.util.stream.Stream).concat(headers.list.stream(), "
+ "{ 'z' }.stream()).collect(T(java.util.stream.Collectors).toList())")
.defaultOverwrite(true))
.log()
.get();
}
Result:
GenericMessage [payload=foo, headers={list=[x, y, z], ...
EDIT
Here's another alternative:
public class MyList<T> extends ArrayList<T> {
public MyList(List<T> original, T... elements) {
super(original);
for (T element : elements) {
add(element);
}
}
}
Then "new com.example.demo.MyList(headers.list, 'z')"
Answered By - Gary Russell
Answer Checked By - Marie Seifert (JavaFixing Admin)