当前位置: 首页 > 知识库问答 >
问题:

spring集成:响应消息未从错误通道发送到客户端

潘志国
2023-03-14

我知道Spring集成(SI)会将任何异常(在SI域下)封装到MessageException实例中,并将其放在“错误通道”上。

以下是我的spring配置文件中的几个片段:

<int:channel-interceptor pattern="ersServiceReqRcvPostValidationChannel,ersServiceResRcvPostValidationChannel" order="1">
    <bean class="com.bnym.ecs.report.service.orchestration.interceptors.MsgJSONSyntaxValidationInterceptor"/>
</int:channel-interceptor>

<int:channel-interceptor pattern="ersServiceReqRcvPostValidationChannel,ersServiceResRcvPostValidationChannel" order="2">
    <bean class="com.bnym.ecs.report.service.orchestration.interceptors.MsgMetaDataValidationInterceptor"/>
</int:channel-interceptor>

<!--  Gateways -->
<int:gateway id="ersServiceReqRcvGateway"
    service-interface="com.bnym.ecs.report.service.orchestration.gateway.ERSOrchestrationSvcReqGateway"
    error-channel="reqRcvExceptionHandlerChannel">
    <int:method name="processRequest" request-channel="ersServiceReqRcvPostValidationChannel" />
</int:gateway>

<!--  Chain to handle all incoming request *after* doing all validations -->
<int:chain input-channel="ersServiceReqRcvPostValidationChannel">
    <int:service-activator ref="msgReqAuditDetailDAOIntegrator" method="persist" />
    <!--  Router -->
    <int:router ref="ersServiceReqRcvRouter" />
</int:chain>

<!--  6) Pass the message through ERS svc to Exec svc ADH chain - Chain2 -->
<int:chain input-channel="ersSvc2execSvcQMRChannel" output-channel="ersServiceResRcvPostValidationChannel">
    <int:transformer ref="json2ObjTransformer" method="transformToERSOrchestrationSvcReq" />
    <int:service-activator ref="executionSvcReqMsgBuilder" method="getRptExecutionSvcReqForDataEngine" />
    <int:transformer ref="obj2JsonTransformer" method="transformFromRptExecutionSvcReqForDataEngine" />
    <int:service-activator ref="msgReqAuditDAOIntegrator" method="persist" />
    <int:service-activator ref="msgReqAuditDetailDAOIntegrator" method="persist" />
    <int:service-activator ref="executionSvcRESTStub" method="executeReportJSON" />
</int:chain>

<int:chain input-channel="reqRcvExceptionHandlerChannel">
    <int:transformer ref="exceptionTransformer" method="handleError"/>
</int:chain>

客户端对我的实现类进行REST调用,该类将接收到的请求放在上面的spring配置文件中定义的网关上

@Path("/reportExecutor")
public class ERSOrchestrationServiceImpl {

    @Autowired
    private ReportInstanceDAO reportInstanceDAO;

    private static final ERSOrchestrationSvcDiagnosticLogger _logger = 
    ERSOrchestrationSvcDiagnosticLogger.getInstance(ERSOrchestrationServiceImpl.class);

    @Context
    HttpServletRequest request;
    @Context
    HttpServletResponse response;

    @POST
    @Path("/executeOnlineReport")
    @Produces({MediaType.APPLICATION_JSON})
    public String executeOnlineReport(String jsonRequest) {

        ApplicationContext appCtx = SpringApplicationContextUtil.getApplicationContext();

        ERSOrchestrationSvcReqGateway ersOrchestrationSvcReqGateway = 
            (ERSOrchestrationSvcReqGateway) appCtx.getBean("ersServiceReqRcvGateway");

        Message<String> inputMsg = MessageBuilder.withPayload(jsonRequest)
                                                 .setHeader(ERSServiceConstants.KEY_MSG_CORRELATION_ID, correlationId)
                                                 .setHeader(ERSServiceConstants.KEY_MSG_REPORT_INSTANCE_ID, reportInstanceId)
                                                 .build();

        Message<String> returnMsg = ersOrchestrationSvcReqGateway.processRequest(inputMsg);
        return returnMsg.getPayload();

    }

如上面的spring配置文件所述,错误通道由转换器读取,该转换器为客户端创建有效的失败响应消息并返回该消息。

public class ErrorMessageUnwrapTransformer {

    @Autowired
    private Gson gsonUtil;
    @Autowired
    private ReportInstanceDAO reportInstanceDAO;
    @Autowired
    private ERSOrchestrationSvcFailedResMsgBuilder executionSvcFailedMsgBuilder;

    private static final ERSOrchestrationSvcDiagnosticLogger _log = 
    ERSOrchestrationSvcDiagnosticLogger.getInstance(ErrorMessageUnwrapTransformer.class); 

    @Transformer
    public Message<?> handleError(Message<?> message) {
        try{
            failedMsg = ((MessagingException) message.getPayload()).getFailedMessage();

            //some code logic to build a valid failed response message goes here
            Message<?> failedResponseMsg = executionSvcFailedMsgBuilder.getERSOrcSvcFailedResMsg(failedMsg );

            return failedResponseMsg;
        }

当我得到一个异常时,一切似乎都正常工作,即异常被包装为MessaginException,放在错误通道上,转换器能够读取通道,从中获取失败消息,能够创建有效的失败响应消息并返回它。

然而,我得到的唯一问题是呼叫不会返回给呼叫方。换句话说,句柄不会返回到启动处理流的以下代码:

Message<String> returnMsg = ersOrchestrationSvcReqGateway.processRequest(inputMsg);   

有人能告诉我为什么错误通道读取转换器返回的消息没有返回到调用网关方法的类吗?

共有1个答案

干宏邈
2023-03-14

您的问题是返回整个消息

为什么这么重要?

由于您使用的是请求/回复网关,因此您希望在该方法调用时得到返回,因此后台的一些东西可以确保这一点。它是一种经典的复制通道算法。

任何AbstractReplyProducingMessageHandler都会将其结果发送到replyChannel,如果您没有配置输出通道,例如您的ReqrcveExceptionHandlerChannel

对于其他组件,我们可以依赖于从请求复制标头功能,但这里不依赖于

从另一方面来看,可能会在某些没有标头的上下文中创建错误消息,但我们确实可能会在导致错误消息的消息异常中创建失败消息。因此,我们必须确保来自该故障消息的标题。

希望我清楚。

 类似资料:
  • 我需要在我的Spring集成上下文中动态地将消息分配给MessageChannel。当我知道我想要的MessageChannel的名称时,我可以通过从上下文中获取MessageChannel bean来做到这一点。 我需要做的是通过编程查找在ChannelAdapter/服务中设置的消息通道的名称/id。 但是,MessageChannel API没有与之关联的getName()或getId()方

  • 我正在使用spring-cloud-stream:1.3.0.发行版、spring-cloud-stream-binder-kafka:1.3.0.发行版开发spring引导应用程序。我使用spring integration dsl拆分文件中的行,使用beanio将行转换为json,要求将成功的json消息写入一个kafka主题,并将错误消息写入不同的kafka主题。下面是application

  • 使用Spring Integration Kafka,使用出站通道适配器,我尝试向名为“test”的主题发送消息 通过命令行终端,我启动了动物园管理员、kafka并创建了名为“test”的主题 Spring XML配置 JUnit测试代码 测试用例成功,在调试时,我发现channel.send()返回true 我使用下面的命令通过命令行检查了主题,但是我在测试主题中看不到任何消息。 bin/kaf

  • 我正在通过绑定到不同Webshpere MQ的入站和出站原子和JMS使用带有JTA支持的Spring集成。流程如下: JMS入站通道适配器收到消息 一些转变 输出队列的JMS出站通道适配器 发生错误时,收到消息 异常类型路由器将未处理的错误路由到自定义重新抛出服务,并将处理的错误路由到接收者列表路由器,该路由器将它们发送到2个错误队列 我的问题是,即使消息到达errorChannel下游(在已处理

  • 问题内容: 我只能在用户的套接字ID直接存储在io.sockets.on(’connect’)函数中时向用户发出消息。我不知道为什么在登录后尝试存储其套接字ID时为什么不起作用。 加工: 无法运作: JavaScript客户端代码段 解决方案:感谢@alessioalex, 我不得不从登录页面中删除对socket.io的引用,并将以下内容添加到io.sockets.on(’connection’)

  • 这是使用注释代码示例的Spring集成执行器通道的后续问题。 我试图通过在“公共频道”中发布一条消息并阅读味精中设置的REPLY_CHANNEL来测试用红色突出显示的框。 “公共通道”是发布-订阅通道。REPLY_通道是一个队列通道。 由于这是一个JUnit测试,我已经模拟了jdbcTemboard、数据源和Impl以忽略任何DB调用。 我的问题是:当我在“公共频道”上发布消息时,我在REPLY\