2013-10-04 58 views
0

我一直在通過互聯網進行搜索並嘗試許多不同的方式,但是我無法使其工作。如何從出站網關向發件人拋出異常

我想要的是捕獲從出站端拋出的異常,例如一些驗證,當它們沒有成功傳遞時它應該向發送端返回一個異常。我不知道是否可以不使用DirectChannel從服務器發送請求。

我希望有人能幫助我。

在下面的代碼中,我向您展示了我的SI配置,其中使用SPEL表達式篩選的「checkRemoteOutputHeaders」在執行時引發異常。

<int:channel id="requestChannelSb"> 
    <int:interceptors> 
     <int:wire-tap channel="timeStampCalllogger" /> 
    </int:interceptors> 
</int:channel> 

<task:executor id="threadPoolTaskExecutor" pool-size="10" queue-capacity="100" rejection-policy="DISCARD_OLDEST" /> 

<bean id="taskExecutor" class="org.springframework.integration.util.ErrorHandlingTaskExecutor"> 
    <constructor-arg name="executor" ref="threadPoolTaskExecutor"/> 
    <constructor-arg name="errorHandler"> 
     <bean class="org.springframework.integration.channel.MessagePublishingErrorHandler"> 
      <property name="defaultErrorChannel" ref="errorChannel"/> 
     </bean> 
    </constructor-arg> 
</bean> 

<int:channel id="gatewayChannelSb"> 
    <int:dispatcher task-executor="taskExecutor" failover="false"/> 

    <int:interceptors> 
     <int:wire-tap channel="timeStampInitlogger" /> 
    </int:interceptors> 
</int:channel> 
<int:channel id="responseChannelSb"> 
    <int:interceptors> 
     <int:wire-tap channel="timeStampEndlogger" /> 
    </int:interceptors> 
</int:channel> 
<int:channel id="errorChannel"> 
    <int:interceptors> 
     <int:wire-tap channel="errorlogger"/> 
    </int:interceptors> 
</int:channel> 


<int-http:outbound-gateway request-channel="requestChannelSb" 
    url="{urlVar}" http-method="POST" 
    extract-request-payload="true" 
    expected-response-type="java.lang.String" 
    charset="UTF-8" 
    header-mapper="headerMapper" 
    reply-channel="responseChannelSb" 
    request-timeout="60000"> 

    <int-http:uri-variable name="urlVar" expression="T(gnf.servicebroker.util.Utils).getUrl(headers)" /> 

</int-http:outbound-gateway> 

<int:chain input-channel="responseChannelSb"> 
    <int:header-enricher> 
     <int:header name="#{T(gnf.servicebroker.util.Constantes$HEADERS).BEAN}" expression="headers[T(gnf.servicebroker.util.Constantes$HEADERS).BEAN]"/> 
    </int:header-enricher> 
    <int:transformer ref="customJsonToObjectTransformer"/> 
</int:chain> 


<int:chain id="chain" input-channel="gatewayChannelSb" output-channel="requestChannelSb"> 

    <int:header-enricher> 
     <int:error-channel ref="errorChannel" overwrite="true"/> 
     <int:header name="#{T(gnf.servicebroker.util.Constantes$HEADERS).REQUEST_ID}" expression="headers[T(gnf.servicebroker.util.Constantes$HEADERS).ID].toString()"/> 
    </int:header-enricher> 

    <int:filter expression="T(gnf.servicebroker.util.Utils).checkRemoteOutputHeaders(headers)" discard-channel="errorChannel" /> 

    <int:header-enricher> 
     <int:header name="#{T(gnf.servicebroker.util.Constantes$HEADERS).CONTENT_TYPE}" value="text/x-json" /> 
     <int:header name="#{T(gnf.servicebroker.util.Constantes$HEADERS).ACCEPT}" value="text/x-json" /> 
     <int:header name="#{T(gnf.servicebroker.util.Constantes$HEADERS).BEAN}" expression="T(gnf.servicebroker.util.Utils).getPayloadCanonicalClassName(payload)" /> 
     <int:header name="#{T(gnf.servicebroker.util.Constantes$HEADERS).SECURITY_USER}" expression="T(gnf.servicebroker.util.Utils).getSecurityUser()"/> 
     <int:header name="#{T(gnf.servicebroker.util.Constantes$HEADERS).TARGET}" expression="T(gnf.servicebroker.util.Utils).getTargetUrl()"/> 
    </int:header-enricher> 

    <int:object-to-json-transformer object-mapper="jsonObjectMapper"/> 
</int:chain> 



<!-- Logging channels --> 

<int:logging-channel-adapter id="timeStampInitlogger" level="INFO" expression="'Inicio de la peticion: '.concat(T(gnf.servicebroker.util.Utils).getRequestInfoTrace(headers))"/> 
<int:logging-channel-adapter id="timeStampCalllogger" level="INFO" expression="'Envio de la peticion: '.concat(T(gnf.servicebroker.util.Utils).getRequestInfoTrace(headers))"/> 
<int:logging-channel-adapter id="timeStampEndlogger" level="INFO" expression="'Final de la peticion: '.concat(T(gnf.servicebroker.util.Utils).getRequestInfoTrace(headers))"/> 
<int:logging-channel-adapter id="destinationCalllogger" level="INFO" expression="'Destino peticion: '.concat(headers[T(gnf.servicebroker.util.Constantes$HEADERS).SUBSYSTEM])"/> 

<int:logging-channel-adapter id="errorlogger" level="ERROR" expression="'ERROR: '.concat(T(gnf.servicebroker.util.Utils).getRequestInfoTrace(headers))"/> 

<!-- End Logging channels --> 


<int:chain input-channel="errorChannel" output-channel="responseChannelSb"> 
    <int:transformer ref="messageHandlingExceptionTransformer"/> 
</int:chain> 

在下面的代碼中,我告訴你,變壓器,「messageHandlingExceptionTransformer」,其中MessaggingException轉換爲ServiceException(自定義除外):

@Transformer 
public Message<ServiceException> transform(ErrorMessage message){ 

    LOGGER.debug("INIT - transform(message=" + message + ")"); 

    MessagingException messageException = (MessagingException) message.getPayload(); 

    ServiceException serviceEx = new ServiceException(messageException.getMessage(), messageException.getCause()); 

    Message<?> originalMsg = messageException.getFailedMessage(); 

    Message<ServiceException> transformedObj = MessageBuilder.withPayload(serviceEx).copyHeaders(originalMsg.getHeaders()).build(); 


    LOGGER.debug("END - transform=" + transformedObj); 

    return transformedObj; 
} 

其他變壓器「customJsonToObjectTransformer」只是轉換一個字符串有效載荷(JSON)並返回給Java對象,但如果有效負載不是字符串(例如異常),則會直接返回該字符串。

Thans提前。

回答

0

最後我發現調用者沒有收到在出站生命週期中拋出的異常的原因。

我只是一個配置問題,因爲在其他XML文件中,我有網關定義,它指出其錯誤通道與出站配置中定義的錯誤通道相同。所以它產生了一個循環調用鏈,因爲在出​​站時,具有異常的ErrorMessage在errorChannel中一次又一次地在網關的錯誤通道中管理,這是相同的,所以請求再次進入鏈中管理errorChannel,最後在未通知調用者的情況下失敗。

<int:gateway id="gcccSearchServiceRequestByCodeServiceSb" 
    service-interface="gnf.servicebroker.gps.atencioncliente.atcomercializadora.servicerequest.service.GcccSearchServiceRequestByCodeServiceISb" 
    default-request-channel="gatewayChannelSb" 
    error-channel="errorChannel"> 
    <int:method name="gcccSearchServiceRequestByIdSr"> 
     <int:header name="Method" value="gcccSearchServiceRequestByIdSr"/> 
     <int:header name="Module" value="atencioncliente"/> 
     <int:header name="Service" value="gnf.servicebroker.gps.atencioncliente.atcomercializadora.servicerequest.service.GcccSearchServiceRequestByCodeServiceISb"/> 
     <int:header name="SubSystem" value="atec-web"/> 
    </int:method> 
</int:gateway> 

通知的錯誤溝道屬性,它具有比在出站配置中的錯誤信道definend相同的值,所以去除該屬性調用者可以捕獲異常:

<int:gateway id="gcccSearchServiceRequestByCodeServiceSb" 
    service-interface="gnf.servicebroker.gps.atencioncliente.atcomercializadora.servicerequest.service.GcccSearchServiceRequestByCodeServiceISb" 
    default-request-channel="gatewayChannelSb"> 
    <int:method name="gcccSearchServiceRequestByIdSr"> 
     <int:header name="Method" value="gcccSearchServiceRequestByIdSr"/> 
     <int:header name="Module" value="atencioncliente"/> 
     <int:header name="Service" value="gnf.servicebroker.gps.atencioncliente.atcomercializadora.servicerequest.service.GcccSearchServiceRequestByCodeServiceISb"/> 
     <int:header name="SubSystem" value="atec-web"/> 
    </int:method> 
</int:gateway> 

我希望對任何人都有幫助。

謝謝!!!