2013-06-03 23 views
2

我瞭解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調用我的實現類inturn放在上面的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配置文件中提到的那樣,Transformer讀取錯誤通道,爲客戶端創建一個有效的失敗響應消息並返回消息。

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; 
     } 

一切似乎當我得到一個例外,即異常包裝爲MessagingException,穿上了錯誤通道做工精細,變壓器能夠讀取通道,得到failedMessage出來,能夠創建有效的失敗響應消息並將其返回。

但是,我得到的唯一問題是電話不會返回給調用者。換句話說,把手不回到那個已經啓動的處理流程如下代碼:

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

有人可以請讓我知道爲什麼該消息通過返回的錯誤通道讀取變壓器不返回回到調用網關方法的類?

+0

我面臨同樣的問題你解決了他的問題嗎? – vbazaga86

回答

0

你的問題在這裏,你從transformer返回整個Message<?>。這是一個不關心標題的組件,當返回的對象已經是Message<?>。您應該自己擔心,比如將failedMsg中的所有標題複製到您自己的failedResponseMsg

爲什麼這麼重要?

由於您使用request/reply網關,您希望獲得該方法調用的返回,因此背景上的某些內容可以確保爲您服務。它是一種經典的replyChannel算法。

任何AbstractReplyProducingMessageHandler發送其結果到replyChannel,如果你沒有一個outputChannel配置,如您reqRcvExceptionHandlerChannel<chain>這裏。

與其他組件我們可以依靠copy-header-from-request函數,但不在這裏與<transformer>

來自對岸ErrorMessage在某些情況下被創建,我們沒有頭,但我們究竟可以在爲其ErrorMessage已經引起了MessagingExceptionfailedMessage。所以,我們必須確保headersfailedMessage

希望我清楚。

相關問題