如何将响应发送回网关接口?

时间:2019-09-27 12:13:05

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

我目前收到此错误:

 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通道,我在日志中可以看到消息到达了contract,input通道,但是在处理程序方法中响应后,我得到了:

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界面。

1 个答案:

答案 0 :(得分:1)

网关是请求-响应组件,为了将它们之间的相关性,在向replyChannel发送消息期间会填充带有TemporaryReplyChannel的{​​{1}}标头。

这在Reference Manual中有清楚的解释。

因此,即使您提供了requestChannel并将其在下游使用,replyChannel = "output"也必须保留在标题中。

您的问题代码在replyChannel中:

@Transformer

您构建了一条新消息,并且没有复制请求标头来咖喱该return MessageBuilder. withPayload(request. getPayload().getContractId()). setHeader("fileType", "CONTRACT").build();

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

因此,您需要考虑在此处添加代码:Message