簡體   English   中英

Spring集成與Spring DSL的“發布訂閱頻道”

[英]Spring Integration “Publish Subscribe Channel” with Spring DSL

我正在嘗試構建一個簡單的流程,在此流程中,我先通過HTTP入站通道適配器接收HTTP發布請求,然后將其發布到“ SubscribableChannel”。 可能有“ N”個用戶訂閱了此頻道。 下圖顯示了流程。

在此處輸入圖片說明

我正在嘗試使用Spring DSL來配置此流程,並且一直無法使其正常工作。 下面是我的代碼。

@Bean
public IntegrationFlow receiveHttpPost() {
    return IntegrationFlows.from(Http.inboundChannelAdapter("/receive")
            .mappedRequestHeaders("*")
            .requestChannel(httpInAdapterPubSubChannel()))
            .transform(new ObjectToStringTransformer())
            .get();
}

@Bean
public SubscribableChannel  httpInAdapterPubSubChannel()
{
    return MessageChannels.publishSubscribe("httpInAdapterPubSubChannel")
    .get();
}

@Bean
public IntegrationFlow subscriber1() {
    return IntegrationFlows.from(httpInAdapterPubSubChannel())
            .handle( message -> System.out.println("Enrich Headers based on Payload...."))
            .get();
}

@Bean
public IntegrationFlow subscriber2() {
     return IntegrationFlows.from(httpInAdapterPubSubChannel())
                .handle( message -> System.out.println("Save Payload to Audit Table..."))
                .get();
}

運行此流程時,出現“無法處理消息;嵌套的異常是org.springframework.messaging.core.DestinationResolutionException:沒有可用的output-channel或replyChannel標頭”

o.s.i.channel.PublishSubscribeChannel    : preSend on channel 'httpInAdapterPubSubChannel', message: GenericMessage [payload=Test, headers={content-length=4, http_requestMethod=POST, accept-language=en-US,en;q=0.8, accept=*/*, host=localhost:8080, http_requestUrl=http://localhost:8080/receive, connection=keep-alive, content-type=text/plain;charset=UTF-8, id=2c6ee729-96ee-1ae5-be31-a9bc56092758, cache-control=no-cache, accept-encoding=gzip, deflate, br, user-agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36, timestamp=1484457726393}]
o.s.i.t.MessageTransformingHandler       : org.springframework.integration.transformer.MessageTransformingHandler#0 received message: GenericMessage [payload=Test, headers={content-length=4, http_requestMethod=POST, accept-language=en-US,en;q=0.8, accept=*/*, host=localhost:8080, http_requestUrl=http://localhost:8080/receive, connection=keep-alive, content-type=text/plain;charset=UTF-8, id=2c6ee729-96ee-1ae5-be31-a9bc56092758, cache-control=no-cache, accept-encoding=gzip, deflate, br, user-agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36, timestamp=1484457726393}]
o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.messaging.MessagingException: Failed to handle Message; nested exception is org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available] with root cause

org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:287) ~[spring-integration-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212) ~[spring-integration-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129) ~[spring-integration-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115) ~[spring-integration-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127) ~[spring-integration-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:236) ~[spring-integration-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:185) ~[spring-integration-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:89) ~[spring-integration-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423) ~[spring-integration-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) ~[spring-messaging-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) ~[spring-messaging-4.3.5.RELEASE.jar:4.3.5.RELEASE]

很明顯,我在這里做錯了什么。 我試圖通過Spring Integration DSL或Java Configuration查找顯示“發布訂閱頻道”的示例。 不幸的是,我找不到任何:-/。 如果有人可以給我提供一個例子,並幫助我找出我的工作流程出了什么問題,我將不勝感激。

我的另一觀察結果是:“當我刪除訂戶的'subscriber1'和'subscriber2'時,我仍然遇到相同的錯誤。 因此,這意味着在配置y HttpInboundAdapter時出現了問題。

另外,如果我將'httpInAdapterPubSubChannel'切換為Direct,並且只有一個路由流(無分支),則一切正常。

.transform(new ObjectToStringTransformer())嘗試將結果發送到某個地方,但它不知道在哪里-入站適配器不希望收到答復,並且轉換器無處發送數據。

也許你的意思是這樣的...

@Bean
public IntegrationFlow receiveHttpPost() {
    return IntegrationFlows.from(Http.inboundChannelAdapter("/receive")
        .mappedRequestHeaders("*"))
        .transform(new ObjectToStringTransformer())
        .channel(httpInAdapterPubSubChannel())
        .get();
}

即將轉換器的結果發送到發布/訂閱通道。

DSL參考有幾個示例。 例如在這里這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM