Cara melempar pengecualian dari gerbang keluar ke pengirim

Saya telah mencari melalui Internet dan mencoba berbagai cara, tetapi saya tidak berhasil.

Yang saya inginkan adalah menangkap pengecualian yang diberikan dari sisi keluar, misalnya beberapa validasi, yang seharusnya mengembalikan Pengecualian ke pengirim ketika pengecualian tersebut tidak berhasil diteruskan. Saya tidak tahu apakah mungkin tanpa menggunakan DirectChannel untuk mengirim permintaan dari server.

Saya harap seseorang dapat membantu saya.

Dalam kode di bawah ini saya menunjukkan konfigurasi SI saya, di mana filter dengan ekspresi SPEL, "checkRemoteOutputHeaders", memunculkan Pengecualian saat dijalankan.

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

Dalam kode berikut saya tunjukkan transformator, "messageHandlingExceptionTransformer", yang mengubah MessaggingException menjadi ServiceException (pengecualian khusus):

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

Transformator lain "customJsonToObjectTransformer" hanya mengonversi payload String (JSON) ke objek Java dan mengembalikannya, tetapi jika payload tersebut bukan String, misalnya pengecualian, maka ia akan mengembalikannya secara langsung.

Terima kasih sebelumnya.


person Alberto    schedule 04.10.2013    source sumber


Jawaban (1)


Akhirnya saya menemukan alasan mengapa penelepon tidak menerima Pengecualian yang diberikan selama siklus hidup keluar.

Saya hanya masalah konfigurasi, karena di file XML lain saya memiliki definisi gateway yang menunjukkan saluran kesalahannya sama dengan yang ditentukan dalam konfigurasi keluar. Jadi itu menghasilkan rantai panggilan siklik, karena di outbound ErrorMessage dengan pengecualian dikelola di errorChannel sekali dan kemudian lagi di saluran kesalahan gateway, yang sama, sehingga petisi masuk lagi ke dalam rantai yang mengelola errorChannel dan akhirnya gagal tanpa memberi tahu penelepon.

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

Perhatikan atribut saluran kesalahan, yang memiliki nilai yang sama dengan yang ditentukan saluran kesalahan dalam konfigurasi keluar, sehingga dengan menghapus atribut ini pemanggil dapat menangkap pengecualian:

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

Saya harap ini membantu siapa pun.

Terima kasih!!!

person Alberto    schedule 07.10.2013