Spring Integration - 出站传输重命名问题

时间:2014-07-29 04:07:30

标签: spring spring-batch spring-integration

我正在使用示例程序here来构建我的代码。使用本地SFTP测试服务器一切正常,当我今天在我的客户端SFTP服务器上测试时,它给了我一个例外,如下所示。

当我调试时,我看到该文件是用' .writing'客户端SFTP服务器上的扩展。内容很好,我没有看到传输文件的任何问题,但文件名现在是问题。通过spring docs阅读后,我看到这是临时文件扩展名,程序会尝试将其重命名为原始名称,但由于客户端SFTP不提供此选项,因此它会抛出异常。

我尝试将temporary-file-suffix=".writing"写为temporary-file-suffix="",这样可以设置选项,唉同样的问题。有工作吗?

其中一个post提到了这一点,但没有任何解决方案或问题因用户而消失。

> 2014-07-28 20:11:21,564 [main] INFO  com.jcraft.jsch - SSH_MSG_NEWKEYS
> sent 2014-07-28 20:11:21,608 [main] INFO  com.jcraft.jsch -
> SSH_MSG_NEWKEYS received 2014-07-28 20:11:21,678 [main] INFO 
> com.jcraft.jsch - SSH_MSG_SERVICE_REQUEST sent 2014-07-28 20:11:21,770
> [main] INFO  com.jcraft.jsch - SSH_MSG_SERVICE_ACCEPT received
> 2014-07-28 20:11:21,818 [main] INFO  com.jcraft.jsch - Authentications
> that can continue: publickey,keyboard-interactive,password 2014-07-28
> 20:11:21,818 [main] INFO  com.jcraft.jsch - Next authentication
> method: publickey 2014-07-28 20:11:21,819 [main] INFO  com.jcraft.jsch
> - Authentications that can continue: keyboard-interactive,password 2014-07-28 20:11:21,819 [main] INFO  com.jcraft.jsch - Next
> authentication method: keyboard-interactive 2014-07-28 20:11:21,978
> [main] INFO  com.jcraft.jsch - Authentication succeeded
> (keyboard-interactive). 2014-07-28 20:11:22,199 [main] DEBUG
> org.springframework.beans.factory.support.DefaultListableBeanFactory -
> Returning cached instance of singleton bean
> 'integrationEvaluationContext' 2014-07-28 20:11:22,878 [main] DEBUG
> org.springframework.integration.sftp.session.SftpSession - Initial
> File rename failed, possibly because file already exists. Will attempt
> to delete file: remote/TESTFILE.ABC and execute rename again.
> 2014-07-28 20:11:22,958 [main] INFO  com.jcraft.jsch - Disconnecting
> from fsgatewaytest.aexp.com port 22 2014-07-28 20:11:22,961 [Connect
> thread fsgatewaytest.aexp.com session] INFO  com.jcraft.jsch - Caught
> an exception, leaving main loop due to Socket closed Exception in
> thread "main" org.springframework.messaging.MessageDeliveryException:
> Error handling message for file [data/TESTFILE.ABC -> TESTFILE.ABC]
>   at
> org.springframework.integration.file.remote.RemoteFileTemplate$1.doInSession(RemoteFileTemplate.java:227)
>   at
> org.springframework.integration.file.remote.RemoteFileTemplate$1.doInSession(RemoteFileTemplate.java:190)
>   at
> org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:302)
>   at
> org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:190)
>   at
> org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:182)
>   at
> org.springframework.integration.file.remote.handler.FileTransferringMessageHandler.handleMessageInternal(FileTransferringMessageHandler.java:101)
>   at
> org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
>   at
> org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
>   at
> org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101)
>   at
> org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
>   at
> org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
>   at
> org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255)
>   at
> org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:223)
>   at
> com.reachlocal.payment.integration.SftpOutboundTransferMain.main(SftpOutboundTransferMain.java:43)
> Caused by: org.springframework.messaging.MessagingException: Failed to
> write to 'inbox/REACHLOCALTST.CUFI.writing' while uploading the file
>   at
> org.springframework.integration.file.remote.RemoteFileTemplate.sendFileToRemoteDirectory(RemoteFileTemplate.java:397)
>   at
> org.springframework.integration.file.remote.RemoteFileTemplate.access$500(RemoteFileTemplate.java:56)
>   at
> org.springframework.integration.file.remote.RemoteFileTemplate$1.doInSession(RemoteFileTemplate.java:213)
>   ... 13 more Caused by: org.springframework.core.NestedIOException:
> Failed to delete file inbox/TESTFILE.ABC; nested exception is
> org.springframework.core.NestedIOException: Failed to remove file: 2:
> Specified file path is invalid.   at
> org.springframework.integration.sftp.session.SftpSession.rename(SftpSession.java:200)
>   at
> org.springframework.integration.file.remote.RemoteFileTemplate.sendFileToRemoteDirectory(RemoteFileTemplate.java:393)
>   ... 15 more Caused by: org.springframework.core.NestedIOException:
> Failed to remove file: 2: Specified file path is invalid.     at
> org.springframework.integration.sftp.session.SftpSession.remove(SftpSession.java:83)
>   at
> org.springframework.integration.sftp.session.SftpSession.rename(SftpSession.java:194)
> ... 16 more

更新配置:使用use-temporary-file-name =" false"解决了这个问题。非常感谢。

<int:channel id="inputChannel"/>

<int-sftp:outbound-channel-adapter id="sftpOutboundAdapter"
            session-factory="sftpSessionFactory"
            channel="inputChannel"
            remote-filename-generator-expression="payload.getName()"
            remote-directory="inbox"
            use-temporary-file-name="false"/>

1 个答案:

答案 0 :(得分:2)

这个use-temporary-file-name怎么样?

在这种情况下,你最终得到了这个:

try {
    session.write(inputStream, tempFilePath);
    // then rename it to its final name if necessary
    if (useTemporaryFileName){
       session.rename(tempFilePath, remoteFilePath);
    }
}

来自提及的文件:

  

但是,可能存在您不想使用此技术的情况(例如,如果服务器不允许重命名文件)。对于这种情况,您可以通过将use-temporary-file-name设置为false来禁用此功能(默认为true)。当此属性为false时,将使用其最终名称编写文件,并且使用应用程序将需要一些其他机制来检测文件在访问之前是否已完全上载。