如何在Spring Cloud Stream聚合器处理器的aggregator.aggregation选项上使用SpEL表达式?

时间:2017-06-11 12:00:44

标签: spring spring-cloud-stream spring-cloud-dataflow

我有三个单独的消息有效负载:

"id": "1234"

"type": "space-crite"

"attributes": {
  "ferocity": 10,
  "appetite": 10,
  "cuddliness": 0
}

我想使用Spring Cloud Stream聚合器-app-starter处理器将这三个消息有效负载合并为一个:

"id": "1234",
"type": "space-crite",
"attributes": {
  "ferocity": 10,
  "appetite": 10,
  "cuddliness": 0
}

使用聚合器处理器的aggregator.aggregation选项。文档说这个属性的有效值是聚合策略的SpEL表达式,默认情况下它生成一组有效负载。聚合器处理器的集成测试之一使用以下表达式:

#this.?[payload == 'foo'].![payload]

从“foo”和“bar”的单独有效负载生成“foo”的聚合消息。 虽然这些测试非常有用,但是文档并没有提供很多关于如何在Spring Cloud Stream Starter应用程序环境中使用SpEL表达式的示例,这是一种耻辱,因为我知道我错过了一个非常强大的特征

使用如下所示的表达式:

 #this

,因为aggregator.aggregation属性的值创建了一个有效内容,该有效内容是GenericMessage对象的集合,每个对象都有自己的有效负载和标头属性。我希望创建一个大小为1的GenericMessage,它具有包含3条传入消息的有效负载属性。

有人能指出一些如何使用此处理器选项使用SpEL表达式的示例吗?我正在尝试的是什么?

1 个答案:

答案 0 :(得分:1)

假设有效载荷是字符串......

尝试get(0).payload + get(1).payload + get(2).payload

如果您想在有效负载之间换行,请使用

T(String).format(get(0).payload + '%n' + get(1).payload + '%n' + get(2).payload)

修改

不幸的是,聚合的#root对象是Collection<Message<?>>而不是List<Message<?>>,因此上述内容无效。

你可以用new java.util.ArrayList(#root).get(0).payload等替换每个元素,但这相当丑陋(而且效率低,因为你创建了一个新的列表来抓取每个元素)。我会看看能不能提出更好的解决方案。

<强> EDIT2

也许这会接近你想要的......

#root.![payload].toString()

测试:

MessageGroup g = new SimpleMessageGroup("foo");
g.add(new GenericMessage<>("foo"));
g.add(new GenericMessage<>("bar"));
Collection<Message<?>> messages = g.getMessages();
Expression e = new SpelExpressionParser().parseExpression(
        "#root.![payload].toString()");
System.out.println(e.getValue(messages));

产生

[foo, bar]

删除大括号:

#root.![payload].toString().replaceAll('[\[\]]', '')

(只要你的JSON中没有[],你的例子就是这种情况)。