Spring integration Spring集成:如何在消息链的中间实现JDCBOutEngEnter网关?

Spring integration Spring集成:如何在消息链的中间实现JDCBOutEngEnter网关?,spring-integration,Spring Integration,在我看来,这似乎是一个很简单的问题,可能会在各地重复出现。MessageHandlerChain的一个非常基本的应用程序,可能只使用开箱即用的功能 从概念上讲,我需要的是: (1) Polled JDBC reader (sets parameters for integration pass) | V (2) JDBC Reader (uses input from (1) to fetch data to feed through channel | V (3

在我看来,这似乎是一个很简单的问题,可能会在各地重复出现。MessageHandlerChain的一个非常基本的应用程序,可能只使用开箱即用的功能

从概念上讲,我需要的是:

(1) Polled JDBC reader (sets parameters for integration pass)
    |
    V
(2) JDBC Reader (uses input from (1) to fetch data to feed through channel
    |
    V
(3) JDBC writer (writes data fetched by (2) to target)
    |
    V
(4) JDBC writer (writes additional data from the original parameters fetched in (1))
我想我需要的是

Flow:
From: JdbcPollingChannelAdapter (setup adapter)
Handler: messageHandlerChain
    Handlers (
       JdbcPollingChannelAdapter (inbound adapter)
       JdbcOutboundGateway (outbound adapter)
       JdbcOutboundGateway (cleanup gateway)
    )
JdbcPollingChannelAdapter没有实现MessageHandler API,因此我不知道如何根据设置步骤读取实际数据

由于JdbcOutboundGateway没有实现MessageProducer API,所以对于出站适配器需要使用什么,我有点不知所措

我应该使用OOB类吗?或者我是否需要以某种方式将这两个适配器包装在BridgeHandler中以使其工作

提前谢谢


编辑(2) 附加配置问题

设置适配器正在将带有两个时间戳列的单行向后拉。“充实页眉”部分正在正确处理它们

但是,当入站适配器执行时,框架将java.lang.Object作为参数传入。不是字符串,不是时间戳,而是实际的java.lang.Object,如
新对象()
中所示

它正在传递正确数量的对象,但内容和数据类型丢失。是否需要配置ExpressionEvaluationSqlParameterSourceFactory

信息:

GenericMessage[payload=[{startTime=2020-11-18:01:34.90944,endTime=2020-11-18:01:34.90944}],headers={startTime=2020-11-18 18:01:34.90944,id=835edf42-6f69-226a-18f4-ade030c16618,timestamp=1605897225384}]

JdbcOutboundGateway中的SQL:

Select t.*, w.operation as "ops" from ADDRESS t
Inner join TT_ADDRESS w 
  on (t.ADDRESSID = w.ADDRESSID)
  And (w.LASTUPDATESTAMP >= :payload.from[0].get("startTime") and w.LASTUPDATESTAMP <= :payload.from[0].get("endTime") )

如果您希望将原始参数向下传送到流中的最后一个网关,则需要将这些参数存储在头中,因为在每个步骤之后,回复消息的有效负载都将不同,并且不再有原始设置数据。这是第一次

第二:如果您处理
IntegrationFlow
和Java DSL,您不需要担心
messageHandlerChain
,因为从概念上讲
IntegrationFlow
本身就是一条链,但要先进得多

我不知道为什么需要使用
JdbcPollingChannelAdapter
根据流开始时来自源的传入消息按需请求数据

您肯定仍然需要使用
JdbcOutboundGateway
来选择
模式。
updateQuery
是可选的,因此网关只需执行
选择
并在回复消息的有效负载中为您返回数据


如果接下来的两个步骤只是“编写”,而不关心结果,那么您可能只需要查看一个
PublishSubscribeChandle
和两个
JdbcMessageHandler
作为订阅方即可。如果没有为
PublishSubscribeChannel
提供
执行器,它们将一个接一个地执行。

这看起来像我正在寻找的。如果我理解,这就是你所说的:集成流(JdbcPollingChannelAdapter->JdbcOutboundGateway(仅适用于选择模式)->JdbcMessageHandler->JdbcMessageHandler)很好。现在让我们来考虑一下:
IntegrationFlow
必须作为bean在应用程序上下文中注册。如果它不流动,并且您没有看到任何错误,那么您确实缺少了bean Part,目前这已经足够接近了。虽然我很想让你为我写下整件事,但我也需要学习如何通过它:d谢谢!我不确定[0]
中的
是什么,但您是否尝试过这样的
:有效负载..startTime
?测试表达式的方法是使用
SpelExpressionParser.parseExpression()
,然后使用
expression.getValue(@Nullable Object rootObject)
rootObject
必须正好是流中的
消息。嗯,也许没有标题。。。您还可以在
句柄(inboundAdapter)
之前考虑使用
拆分器()。或者查看
JdbcPollingChannelAdapter.setMaxRows(1)
是否足以避免处理集合。
private JdbcPollingChannelAdapter setupAdapter; // select only
private JdbcOutboundGateway inboundAdapter; // select only
private JdbcOutboundGateway insertUpdateAdapter; // update only
private JdbcOutboundGateway deleteAdapter; // update only
private JdbcMessageHandler cleanupAdapter; // update only

        setFlow(IntegrationFlows
            .from(setupAdapter, c -> c.poller(Pollers.fixedRate(1000L, TimeUnit.MILLISECONDS).maxMessagesPerPoll(1)))
            .enrichHeaders(h -> h.headerExpression("ALC_startTime", "payload.from[0].get(\"ALC_startTime\")")
                    .headerExpression("ALC_endTime", "payload.from[0].get(\"ALC_endTime\")"))
            .handle(inboundAdapter)
            .enrichHeaders(h -> h.headerExpression("ALC_operation", "payload.from[0].get(\"ALC_operation\")"))
            .handle(insertUpdateAdapter)
            .handle(deleteAdapter)
            .handle(cleanupAdapter)
            .get());

flowContext.registration(flow).id(this.getId().toString()).register();