Spring集成Java DSL SFTP异常处理

Spring集成Java DSL SFTP异常处理,spring,spring-integration,spring-integration-dsl,spring-integration-sftp,Spring,Spring Integration,Spring Integration Dsl,Spring Integration Sftp,我正在使用spring集成进行文件传输 下面的代码工作正常,但若我从源目录中删除该文件夹,它将开始抛出异常 IntegrationFlow flow = IntegrationFlows.from(Sftp.inboundAdapter(inboundSftp) .localDirectory(new File(classLoader.getResource(".").getFile() + "/files/" + String.valueOf(config.getId(

我正在使用spring集成进行文件传输

下面的代码工作正常,但若我从源目录中删除该文件夹,它将开始抛出异常

IntegrationFlow flow = IntegrationFlows.from(Sftp.inboundAdapter(inboundSftp)
            .localDirectory(new File(classLoader.getResource(".").getFile() + "/files/" + String.valueOf(config.getId())))
            .deleteRemoteFiles(true)
            .autoCreateLocalDirectory(true)
            .remoteDirectory(config.getInboundDirectory()), e -> e.poller(Pollers.fixedDelay(4_000)))
            .transform((File f) -> pgpEncryption.encrypt(f))
            .handle(Sftp.outboundAdapter(outboundSftp)
                    .useTemporaryFileName(false)
                    .autoCreateDirectory(true)
                    .remoteDirectory(config.getOutboundDirectory()), c -> c.advice(sftpConfig.deleteFileAdvice())
            )
            .get();
如果源文件夹不存在,则以下是例外情况

2018-10-01 17:13:02.362 ERROR 12320 --- [ask-scheduler-8] o.s.integration.handler.LoggingHandler   : org.springframework.messaging.MessagingException: Problem occurred while synchronizing remote to local directory; nested exception is org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is org.springframework.core.NestedIOException: Failed to list files; nested exception is 2: No such file
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.synchronizeToLocalDirectory(AbstractInboundFileSynchronizer.java:331)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.doReceive(AbstractInboundFileSynchronizingMessageSource.java:260)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.doReceive(AbstractInboundFileSynchronizingMessageSource.java:65)
    at org.springframework.integration.endpoint.AbstractFetchLimitingMessageSource.doReceive(AbstractFetchLimitingMessageSource.java:43)
    at org.springframework.integration.endpoint.AbstractMessageSource.receive(AbstractMessageSource.java:154)
    at org.springframework.integration.endpoint.SourcePollingChannelAdapter.receiveMessage(SourcePollingChannelAdapter.java:243)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:262)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.lambda$run$0(AbstractPollingEndpoint.java:391)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.lambda$execute$0(ErrorHandlingTaskExecutor.java:57)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:55)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:385)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is org.springframework.core.NestedIOException: Failed to list files; nested exception is 2: No such file
    at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:445)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.synchronizeToLocalDirectory(AbstractInboundFileSynchronizer.java:286)
    ... 20 more
Caused by: org.springframework.core.NestedIOException: Failed to list files; nested exception is 2: No such file
    at org.springframework.integration.sftp.session.SftpSession.list(SftpSession.java:103)
    at org.springframework.integration.sftp.session.SftpSession.list(SftpSession.java:50)
    at org.springframework.integration.file.remote.session.CachingSessionFactory$CachedSession.list(CachingSessionFactory.java:218)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.lambda$synchronizeToLocalDirectory$1(AbstractInboundFileSynchronizer.java:287)
    at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:436)
    ... 21 more
Caused by: 2: No such file
    at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2873)
    at com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2225)
    at com.jcraft.jsch.ChannelSftp._stat(ChannelSftp.java:2242)
    at com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1592)
    at com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1553)
    at org.springframework.integration.sftp.session.SftpSession.list(SftpSession.java:91)
    ... 25 more
那么,捕获此异常并记录相应消息的方法是什么呢。
我还将遇到一些其他问题,如无效的服务器ip、无效的私钥。

默认情况下,执行消息期间的所有异常都会发送到“errorChannel”
您可以在此通道上定义服务激活器,并提供异常处理逻辑

@Bean
@ServiceActivator(inputChannel = "errorChannel")
public MyExceptionHandler exceptionHandler() {
  return new MyExceptionHandler ();
}

见-

默认情况下,
o.s.integration.handler.LoggingHandler:org.springframework.messaging.MessagingException:
实际上来自配置到
SourcePollingChannelAdapter
的全局
errorChannel
。您可以通过
SourcePollingChannelAdapterSpec
及其
poller()
配置提供您自己的变体:

e -> e.poller(Pollers.fixedDelay(4_000).errorChannel(myErrorChannel))

这个自定义频道可以像任何其他频道一样订阅,在那里你可以用任何你需要的方式处理
ErrorChannel
。可以使用
@ServiceActivator
或其他
集成流

在上载文件之前,您应该检查目录是否存在。如果目录不存在,应该创建一个。你能给我举个例子吗?我有10多个IntegrationFlows正在运行,如何检查这个异常是从哪个集成开始的
@ServiceActivator(inputChannel=“errorChannel”)公共消息errorChannelHandler(ErrorMessage ErrorMessage){}
我可以在这里访问消息付费负载并返回
MessageBuilder
,但它仍然登录控制台,并且我需要获取此集成流的id。正如我所说的:您可以使用自定义通道处理错误。无需依赖全局
错误通道
。这样,每个流都有自己的错误处理。而且不需要引入一些分离的逻辑。无法在消息中获取流id:没有相关的。第一个只是一个逻辑容器,用于提高源代码的可读性。第二个是活动数据传输对象。实际上,它甚至可能不知道它传递的任何通道和处理程序。