【问题标题】:How do i send response back to Gateway interface?如何将响应发送回网关接口?
【发布时间】:2019-09-27 12:13:05
【问题描述】:

我目前收到此错误:

 DestinationResolutionException: 
     no output-channel or replyChannel header available .  

我有一个注入控制器的文件网关

@MessagingGateway
public interface FileGateway {
    @Gateway(requestChannel = "router.input", replyChannel = "output")
    FileRequestResponse requestFile(FileRequestRequest fileFetchRequest);
}

以及向各自通道发送消息的路由器

@Bean
IntegrationFlow routeFileRequest() {
    return IntegrationFlows.from("router.input")
            .<FileRequestRequest, FileType>route(m -> m.getParameters().getFileType(), m -> m
                    .channelMapping(FileType.CONTRACT, "contract.transform")
                    .channelMapping(FileType.INVOICE, "invoice.tranform"))
            // .channelMapping(FileType.USAGE, "usageChannel"))
            .get();
}

这里是我的转换器 bean,将消息转换为字符串并发送到 contract.input channel,我可以在日志中看到消息到达 contract,input channel,但是在处理程序方法中的响应后我得到:

org.springframework.messaging.core.DestinationResolutionException:
    no output-channel or replyChannel header available. 

变压器:

@Transformer(inputChannel = "contract.transform", outputChannel = "contract.input")
public Message<String> transformContractMessage(Message<FileRequestRequest> request) {
    /**
     *
     *  @param request
     *  @return contractId
     */
    FileRequestRequest frr = request.getPayload();

    return MessageBuilder.
            withPayload(request.
                    getPayload().getContractId()).
            setHeader("fileType", "CONTRACT").build();
}

下面是将消息发送回 router.output 的服务激活器,但是我在上面遇到了那个异常。

@ServiceActivator(inputChannel = "contract.input" ,outputChannel = "output")
public FileRequestResponse res(Message<String> message){
    log.info(" Retrieving File With Contract ID {} ",message.getPayload());
    ContractRsp contractResponse = contractFetchService.retrieveContract(message.getPayload());
    log.info(" Contract File Received {} ",contractResponse);

    return FileRequestResponse.builder().build();
}
@Bean
public DirectChannel output(){
    DirectChannel channel = new DirectChannel();

    return channel;
}

我的目的是在响应后将消息返回到 FileGateway 界面。

【问题讨论】:

    标签: spring-boot spring-integration spring-integration-dsl


    【解决方案1】:

    网关是一个请求-回复组件,在将消息发送到requestChannel 期间,会填充带有TemporaryReplyChannelreplyChannel 标头,以便在它们之间建立关联。

    这在Reference Manual中有明确的解释。

    因此,即使您提供 replyChannel = "output" 并在下游某处使用它,replyChannel 也必须保留在标头中。

    您的问题代码在@Transformer

    return MessageBuilder.
            withPayload(request.
                    getPayload().getContractId()).
            setHeader("fileType", "CONTRACT").build();
    

    您构建了一条新消息,并且不复制请求标头来咖喱 replyChannel

    与许多其他组件(例如@ServiceActivator)不同,如果从转换函数返回Message 实例,则转换器不会将标头复制到回复消息中。

    所以,你需要考虑在你的代码中添加这个:copyHeaders(request.getHeaders())

    【讨论】:

    • 好吧,您需要从该转换器方法返回一个 payload 或消息,但带有复制的请求标头。
    猜你喜欢
    • 2020-10-13
    • 2015-05-13
    • 1970-01-01
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    • 2021-06-06
    • 2017-04-21
    相关资源
    最近更新 更多