วิธีส่งข้อยกเว้นจากเกตเวย์ขาออกไปยังผู้ส่ง

ฉันค้นหาผ่านอินเทอร์เน็ตและลองใช้วิธีต่างๆ มากมาย แต่ก็ไม่สามารถทำงานได้

สิ่งที่ฉันต้องการคือการตรวจจับข้อยกเว้นที่ส่งออกจากฝั่งขาออก เช่น การตรวจสอบความถูกต้องบางอย่าง ซึ่งควรส่งคืนข้อยกเว้นไปยังผู้ส่งเมื่อส่งผ่านไม่สำเร็จ ฉันไม่รู้ว่าเป็นไปได้หรือไม่โดยไม่ใช้ 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" เพียงแปลง String payload (JSON) เป็นอ็อบเจ็กต์ Java และส่งคืน แต่ถ้าเพย์โหลดไม่ใช่ String เช่น ข้อยกเว้น ก็จะส่งคืนโดยตรง

ขอบคุณล่วงหน้าครับ.


person Alberto    schedule 04.10.2013    source แหล่งที่มา


คำตอบ (1)


ในที่สุดฉันก็พบสาเหตุที่ผู้โทรไม่ได้รับข้อยกเว้นที่เกิดขึ้นระหว่างวงจรการใช้งานขาออก

ฉันเป็นเพียงปัญหาการกำหนดค่า เนื่องจากในไฟล์ 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>

โปรดสังเกตแอตทริบิวต์ ช่องสัญญาณข้อผิดพลาด ซึ่งมีค่าเดียวกันกับช่องสัญญาณข้อผิดพลาดที่กำหนดในการกำหนดค่าขาออก ดังนั้นการลบคุณลักษณะนี้ออก ผู้เรียกสามารถตรวจจับข้อยกเว้นได้:

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

ฉันหวังว่ามันจะช่วยทุกคน

ขอบคุณ!!!

person Alberto    schedule 07.10.2013