Как в весенней интеграции отловить разные исключения?

В весенней интеграции у меня есть простой клиентский канал TCP: шлюз, исходящий шлюз TCP, активатор службы и канал ошибок. В tcp-connection-factory есть простой перехватчик. Канал ошибок очень простой, я реализовал адаптер tcp-connection-event-inbound-channel с этим фильтром:

  • org.springframework.integration.ip.tcp.connection.TcpConnectionExceptionEvent.

Итак, мой обработчик ошибок очень простой, выглядит так:

public class TcpErrorHandler {
    public void onException(){
        System.out.println("Exception!!! ");
    } 
}

Это работает, потому что, когда у меня есть исключение закрытия сокета (на стороне сервера я закрываю соединение), приложение пишет «Исключение !!!» к консоли, но с другой стороны, это не работает, когда у меня есть исключение тайм-аута соединения. У меня следующие вопросы: как получить все наиболее важные для меня исключения:

  • Исключение закрытия сокета среды выполнения
  • Исключение тайм-аута подключения
  • Прочие исключения

Есть какой-нибудь механизм ловли?

Вот фрагмент из моей конфигурации bean-компонента:

<!-- Client side -->

<int:gateway id="gw"
    service-interface="hu.gmxdev.climaxreplica.service.SimpleGateway"
    default-request-channel="outputchannel" />

<int-ip:tcp-connection-factory id="client"
    type="client" host="localhost" port="10001" single-use="true"
    so-timeout="2000" deserializer="climaxDeserializer"
    interceptor-factory-chain="customInterceptorFactoryChain"/>

<int:channel id="outputchannel" />

<int-ip:tcp-outbound-gateway id="outGateway"
    request-channel="outputchannel" reply-channel="replychannel"
    connection-factory="client" request-timeout="2000" reply-timeout="2000" />

<int:service-activator input-channel="replychannel"
    method="reply" ref="echoService" id="serviceactivator">
</int:service-activator>

<int:channel id="replychannel"></int:channel>

<bean id="customInterceptorFactoryChain"
        class="org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain">
        <property name="interceptors">
            <array>
                <bean class="hu.gmxdev.climaxreplica.service.CustomInterceptorFactory"/>
            </array>
        </property>
</bean>

<!-- Error channel -->

<int-ip:tcp-connection-event-inbound-channel-adapter id="event"
    error-channel="errorChannel"
    event-types="org.springframework.integration.ip.tcp.connection.TcpConnectionExceptionEvent" />

<int:channel id="errorChannel"></int:channel>

<int:service-activator ref="tcpErrorHandler" method="onException"
    input-channel="errorChannel">
</int:service-activator>

А вот и мой обработчик ошибок:

public class TcpErrorHandler {
    @Autowired
    private ApplicationContext appContext;

    public void onException(TcpConnectionExceptionEvent event){
        MainService mainService = appContext.getBean(MainService.class);
        mainService.setSuccess(3);
        System.out.println("Exception!!! ");
        System.out.println(event.getCause().getMessage());
    }
}

Перехватчик здесь:

public class CustomInterceptor extends TcpConnectionInterceptorSupport{

    public CustomInterceptor () {
        System.out.println("catched_constructor1");
    }

    public CustomInterceptor (ApplicationEventPublisher applicationEventPublisher) {
        super(applicationEventPublisher);
        System.out.println("catched_constructor");
    }

    @Override
    public boolean onMessage(Message<?> message) {
        System.out.println("catched_message");
        return super.onMessage(message);
    }


    @Override
    public void send(Message<?> message){
        System.out.println("catched_send");
        MessageHeaders mh = message.getHeaders();
        try {
            super.send(message);
        }
        catch (Exception e) {
            System.out.println("catched_send_exception");
        }
    }

    @Override
    public void close() {
        String id = getConnectionId();
        System.out.println("catched_closed" + id);
        super.close();
    }

}

И мой «звонящий»:

success = gateway.send("fooooooo");

person Viktor Gintner    schedule 30.10.2014    source источник
comment
См. Ссылку tutorialspoint.com/spring/spring_exception_handling_example.htm.   -  person Darshan Lila    schedule 30.10.2014


Ответы (2)


Фактически <tcp-connection-event-inbound-channel-adapter> отправьте channel a Message с TcpConnectionExceptionEvent (в вашем случае) как payload.

Следовательно, ваш подписчик (ваш TcpErrorHandler) может принимать TcpConnectionExceptionEvent в качестве аргумента метода.

В этом методе вы можете выполнить дополнительную логику, например извлеките оригинальный Exception из этого IntegrationEvent.

В модуле IP есть несколько мест, когда используется TcpConnectionSupport.publishConnectionExceptionEvent.

Если вы скажете, что не поймаете time out exception, будет здорово, если вы поделитесь журналами по этому поводу. Интересно, какое место мы не try...catch на _14 _...

ОБНОВЛЕНИЕ

<int-ip:tcp-connection-event-inbound-channel-adapter channel="events" 
    event-types="org.springframework.integration.ip.tcp.connection.TcpConnectionExceptionEvent"/>

<service-activator input-channel="events" ref="tcpErrorHandler"/>

public class TcpErrorHandler {

   public void onException(TcpConnectionExceptionEvent event) {
       System.out.println("Exception!!! ");
       event.getCause();
       ....
   } 

}

Это должно сработать.

ОБНОВЛЕНИЕ2

Согласно вашему коду:

try {
   super.send(message);
}
catch (Exception e) {
    System.out.println("catched_send_exception");
}

Вам не кажется, что там задушить Исключение плохо?

С другой стороны: не могли бы вы включить DEBUG уровень ведения журнала для категории org.springframework.integration и поделиться здесь журналами, когда вы уверены, что ваш tcpErrorHandler должен быть вызван?

С другой стороны, попробуйте <int-ip:tcp-connection-event-inbound-channel-adapter> вообще без event-types. Я имею в виду, давайте посмотрим, обработает ли он какой-нибудь IpIntegrationEvent.

person Artem Bilan    schedule 30.10.2014
comment
Привет, Билан! Вы так думали? открытый класс TcpErrorHandler {public void onException (событие TcpConnectionExceptionEvent) {System.out.println (Exception !!!); System.out.println (Сообщение: + event.getCause (). GetMessage ()); }} Как мне ввести TcpConnectionExceptionEvent ??? Аннотации? Как? - person Viktor Gintner; 31.10.2014
comment
Да, это так. Вам не нужно заботиться о injection. Это ответственность структуры. И мы называем это POJO method invocation. Если вы введете свой TcpErrorHandler в <service-activator> из channel из этого <tcp-connection-event-inbound-channel-adapter>, все будет в порядке. - person Artem Bilan; 31.10.2014
comment
Извините, но я этого не понимаю. Не могли бы вы опубликовать мне очень короткий и простой, но работоспособный пример? (Извините, но я только начал работать со Spring Integration ...) - person Viktor Gintner; 31.10.2014
comment
К ответу добавлен образец - person Artem Bilan; 31.10.2014
comment
Как вы можете видеть мой первый комментарий выше, я пробовал это, но это вообще не работает. Если я добавлю аргумент TcpConnectionExceptionEvent к моему методу - как вы написали - метод никогда не будет вызываться, мой метод никогда не будет Sysout Exception! к консоли! - person Viktor Gintner; 31.10.2014
comment
Добавил мои бобы и классы в исходный вопрос - person Viktor Gintner; 31.10.2014
comment
Я обнаружил ошибку в моем int-ip: tcp-connection-event-inbound-channel-adapter. Я использовал канал ошибок вместо входного. Я исправил это, и после того, как я смог поймать больше исключений - как вы упомянули выше, - я не могу поймать исключение тайм-аута, если нет соединения между клиентом и сервером, например, сервер не слушает порт. Я попробую ваше предложение и включу отладку. - person Viktor Gintner; 31.10.2014
comment
Замечательно! Хорошо. Я бы сказал, что это отдельный ТАК вопрос. Мы исправили здесь вашу проблему с event listener. Примем ответ и начнем новую тему со ссылкой на эту. - person Artem Bilan; 31.10.2014
comment
Хорошо, я ценю вашу помощь! - person Viktor Gintner; 31.10.2014

Вы можете определить канал ошибки, который вы предоставляете своему входящему адаптеру. Вот пример:

    <int:channel id="error-channel"></int:channel>
    <int-ws:inbound-gateway id="gateway" error-channel="error-channel"
    request-channel="in"  marshaller="marshaller" unmarshaller="marshaller"
    reply-channel="out" />

Теперь все исключения, которые выбрасываются в нисходящем направлении, будут перехвачены этим каналом ошибок. Затем вы можете определить активатор службы с этим каналом ошибки в качестве входа:

 <int:service-activator  input-channel="error-channel"
        ref="exceptionHandler" method="handleError" output-channel="outError"></int:service-activator>

И этот активатор относится к bean-компоненту, который определяет логику обработки ошибок.

person nsanglar    schedule 30.10.2014