在Spring Integration中使用发布订阅频道

时间:2017-08-02 02:36:04

标签: spring spring-integration

我们为休息服务和Oracle Stored Proc提供以下XML配置。用例是关于处理Oracle SP错误。

当Oracle SP抛出错误时,我们需要实现两件事:

  1. 我们需要以格式将json响应发送回客户端 {“status”:false,“message”:“Oracle SP错误有效负载”}

  2. 发送电子邮件。

  3. 当Oracle SP抛出错误时,配置按预期工作。但是当电子邮件发送失败(给错误的主机)时,客户端收到以下格式的错误。不会发回Oracle SP错误消息。

    ---- Json message received by client when email send fails:------
    {
     "timestamp": 1501639940143,
     "status": 500,
     "error": "Internal Server Error",
     "exception": "org.springframework.messaging.MessagingException",
     "message": "failure occurred in error-handling flow; nested exception is org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.integration.handler.MessageHandlerChain#0$child#2.handler]; nested exception is org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Unknown SMTP host: xxx.com;..",
     "path": "/init/5c82d1f4-e550-4bb1-be9c-8d0ddbc7f4401/NEW"
    }
    

    如何以预期的json格式发送响应 - {“status”:false,“message”:Oracle SP错误有效负载}?

    另外如何处理电子邮件发送错误。可能是如何将电子邮件错误存储在数据库表中?

    XML配置:

    <int:channel id="spOutClobChannel"/>
    <int:publish-subscribe-channel id="gatewayErrorChannel"/>
    
    
    <int-http:inbound-gateway
        request-channel="gatewayInitChannel"
        error-channel="gatewayErrorChannel"
        supported-methods="GET"
        path="/init/{refId}/{refStatus}"        
        payload-expression="#pathVariables.refStatus">
    
      <int-http:header name="UNIQUE_PROCESS_ID" expression="#pathVariables.refId"/>
    
    </int-http:inbound-gateway>
    
    <int-jdbc:stored-proc-outbound-gateway
                id="sp-get-data"
                data-source="dataSource"
                request-channel="gatewayInitChannel"
                reply-channel="spOutClobChannel".... >
        ...
        ...             
    </int-jdbc:stored-proc-outbound-gateway>
    
    
    <int:transformer input-channel="spOutClobChannel"    expression='{"status": true, "message": "RECEIVED"}'/>
    <int:transformer input-channel="gatewayErrorChannel" expression='{"status": false,"message": payload.message}'/>
    
    <int:transformer expression="payload.failedMessage.headers['UNIQUE_PROCESS_ID']"   
                   input-channel="gatewayErrorChannel" output-channel="appEmailChannel"/>
    
    <int:chain input-channel="appEmailChannel" >
        <int-mail:header-enricher>
            <int-mail:from     value="${email.from}"/>
            <int-mail:to       value="${email.to}"/>
            <int-mail:subject  value="${email.subject}"/>
            <int-mail:content-type value="text/html"/>
       </int-mail:header-enricher> 
       <int-mail:outbound-channel-adapter   host="${email.host}" />
    </int:chain>    
    

1 个答案:

答案 0 :(得分:1)

为了避免appEmailChannel流程中出现的错误,加上获得的收益不等待成功发送电子邮件,最好添加到gatewayErrorChannel executor配置中。这样,该发布 - 订阅者通道的所有订阅者将并行地并且在他们自己的线程中执行。因此,这些线程中的任何异常都不会影响您使用

完成的<int-http:inbound-gateway>的回复
<int:transformer input-channel="gatewayErrorChannel" expression='{"status": false,"message": payload.message}'/>
  

另外如何处理电子邮件发送错误。可能是如何将电子邮件错误存储在数据库表中?

有了这个目标,您可以将ExpressionEvaluatingRequestHandlerAdvicetrapException = truefailureChannel属性结合使用。

可以使用request-handler-advice-chain子元素配置此建议。

有关此事,请参阅Reference ManualSample