小编典典

在Spring集成中,如何捕获不同的异常?

java

在春季集成中,我有一个简单的tcp客户管道:一个网关,一个tcp出站网关,一个服务激活器以及一个错误通道。在tcp-connection-
factory中有一个简单的拦截器。错误通道非常简单,我使用此过滤器实现了tcp-connection-event-inbound-channel-
adapter:

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

所以我的错误处理程序非常简单,看起来像这样:

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

它之所以有效,是因为当我有一个Socket close Exception(服务器端我关闭了连接)时,应用程序会写“ 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");

阅读 216

收藏
2020-11-30

共1个答案

小编典典

实际上<tcp-connection-event-inbound-channel- adapter>发送给channel一个MessageTcpConnectionExceptionEvent(在你的情况下)的payload

因此,您的订阅者(您的TcpErrorHandler)可以接受TcpConnectionExceptionEvent作为方法参数。

在该方法中,您可以进行进一步的逻辑处理,例如从中提取原始Exception内容IntegrationEvent

使用IP时模块中有多个位置TcpConnectionSupport.publishConnectionExceptionEvent

如果您说不了解time out exception,那么如果您共享此事的日志,那就太好了。我不知道我们做哪个地方不try...catchSocketTimeoutException

更新

<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

2020-11-30