Spring Integration请求响应流中Filter断言为false的消息处理问题
Spring Integration中Filter组件在请求-响应流的条件执行与响应保证
问题描述
我在Spring Integration 5.5.17的请求-响应流中,想用filter()实现条件执行,同时确保始终返回响应。比如要实现仅对奇数负载执行乘2操作,我写了如下可行的代码:
@Bean(name = "sendsEvenValuesWorksFlow") IntegrationFlow sendEvenValuesWorksFlow() { return IntegrationFlows.from("sendsEvenValuesWorksChannel") .filter("(payload % 2) == 1", filterSpec -> filterSpec.discardFlow(noop())) .transform("payload * 2") .get(); } private static IntegrationFlow noop() { return f -> f.filter("true"); }
这里给filter配置了一个空操作的discardFlow,但我觉得应该有更简单的方式让不符合条件的消息带着当前负载继续流转。比如下面的代码就因为没有输出消息而无法工作:
@Bean(name = "sendsEvenValuesFailsFlow") IntegrationFlow sendEvenValuesFailsFlow() { return IntegrationFlows.from("sendsEvenValuesFailsChannel") .filter("(payload % 2) == 1") .transform("payload * 2") .get(); }
请问使用filter()方法时,必须借助discard机制(flow或channel)才能保证返回响应消息吗?如果是,有没有更简单的方式创建空操作流?
解答
- 是的,在请求-响应场景下,要保证所有消息都能产生响应,必须通过
discard机制处理不符合过滤条件的消息——因为默认情况下,Filter组件会直接丢弃不符合条件的消息,不会向下游传递,也就无法生成响应。 - 你可以用更简洁的方式创建空操作的discard流,不需要额外定义
noop()方法:直接通过filterSpec.discardFlow(f -> f)即可,这个写法会让被丢弃的消息直接进入后续的流转链路,相当于“无操作”传递原负载。
修改后的可行代码可以简化成:
@Bean(name = "sendsEvenValuesWorksFlow") IntegrationFlow sendEvenValuesWorksFlow() { return IntegrationFlows.from("sendsEvenValuesWorksChannel") .filter("(payload % 2) == 1", filterSpec -> filterSpec.discardFlow(f -> f)) .transform("payload * 2") .get(); }
另外,还有一种更直观的思路:如果你的需求是“对奇数执行乘2,偶数直接返回原负载”,也可以不用Filter,直接在transform里加条件判断,比如:
@Bean(name = "alternateFlow") IntegrationFlow alternateFlow() { return IntegrationFlows.from("alternateChannel") .transform(payload -> { if ((Integer) payload % 2 == 1) { return (Integer) payload * 2; } return payload; }) .get(); }
这种方式同样能保证所有消息都得到处理并返回响应。
内容的提问来源于stack exchange,提问作者al.truisme
相关产品推荐
相关产品推荐

