2013-06-03 1 views
2

SI (Spring Integration)가 SI 도메인 아래의 예외를 MessageException 인스턴스로 래핑하고 "오류 채널 ". 다음스프링 통합 : 오류 채널에서 응답 메시지가 클라이언트에 전송되지 않음

내 스프링 설정 파일에서 몇 조각입니다 : 클라이언트가 어떤 inturn 위의 스프링 설정 파일에 정의 된 게이트웨이에서 수신 된 요청을 배치 내 구현 클래스에 REST 호출을

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

@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(); 

    } 

위의 스프링 설정 파일에서 언급했듯이 error-channel은 클라이언트에 대해 유효한 실패한 응답 메시지를 생성하고 메시지를 반환하는 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; 
     } 

모든 I 오류 채널에 넣어 예외, 즉, 예외가 MessagingException의로 싸여를 얻을 때 잘 작동하는 것 같다, Transformer는, 수 그것의 failedMessage를, 채널을 읽을 얻을 수있다 유효한 실패한 응답 메시지를 작성하여 리턴하십시오.

그러나 내가 얻는 유일한 문제는 호출자가 호출자에게 돌아 가지 않는다는 것입니다. 즉, 핸들은 처리 흐름을 시작했던 다음 코드로 돌아갈하지 않습니다

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

사람이 pls는 메시지에 의해 반환되는 이유를 알려 수있는 오류 채널 읽기 변압기 다시 반환하지 게이트웨이 메소드를 호출 한 클래스에?

+0

나는 동일한 문제에 직면하고있다. 당신은 그의 문제를 해결 했습니까? – vbazaga86

답변

0

여기서 transformer의 전체 Message<?>을 반환하는 것이 좋습니다. 이것은 반환 된 객체가 이미 Message<?> 일 때 헤더를 신경 쓰지 않는 구성 요소입니다. failedMsg에있는 모든 헤더를 자신의 failedResponseMsg으로 복사하는 것처럼 스스로에 대해 걱정해야합니다.

왜 그렇게 중요한가요?

request/reply 게이트웨이를 사용하면 해당 메소드 호출에 대한 수익을 기대하기 때문에 배경에있는 내용을 확인하십시오. 그리고 이것은 고전적인 알고리즘 인 replyChannel입니다. 당신이 outputChannel가 여기 reqRcvExceptionHandlerChannel<chain>처럼 구성되어 있지 않은 경우에

는 모든 AbstractReplyProducingMessageHandlerreplyChannel에 그 결과를 전송한다.

다른 구성 요소를 사용하면 copy-header-from-request 함수에 의존 할 수 있지만 여기서는 <transformer>이 아닙니다. 우리는 헤더가없는 경우 다른 쪽 ErrorMessage에서

어떤 맥락에서 만들 수 있습니다,하지만 우리는 정확히 ErrorMessage가 발생 된의 MessagingException에서 failedMessage을 가질 수있다. 따라서 failedMessage에서 headers을 확인해야합니다.

희망 나는 분명하다.

관련 문제