【问题标题】:Spring Integration SFTP Delete Remote File On DemandSpring集成SFTP按需删除远程文件
【发布时间】:2020-04-29 20:03:34
【问题描述】:

当我的应用中发生某些事情时,我试图从远程 SFTP 存储桶中删除单个文件(我们将文件保存到 blob 存储)。我无法做到这一点。我所能看到的只是在处理完成后始终通过出站通道适配器删除文件。我正在使用 Java 配置。

这是我的代码:

@Bean
@ServiceActivator(inputChannel = "sftpDeleteChannel")
public MessageHandler deleteHandler(SftpInboundProperties properties) {
    SftpOutboundGateway SFTP = new SftpOutboundGateway(sftpSessionFactory(properties), "rm", "'" + properties.getRemoteDirectory() + "'");
    return SFTP;
}

@Gateway(requestChannel = "sftpDeleteChannel")
    Boolean delete(Message<File> file);

这是方便输入文件的服务激活器:

@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler(FileProcessingService fileProcessingService) {
    return message -> {
        fileProcessingService.processFile((Message<File> message);
    };
}

我收到此错误消息:

收到回复消息,但接收线程在发送请求消息时因异常退出:ErrorMessage [payload=org.springframework.messaging.MessageHandlingException: error occurred in message handler [bean 'deleteHandler';定义在:'类路径资源 [com/.../SftpInboundConfiguration.class]';来源:'org.springframework.core.type.classreading.SimpleMethodMetadata@6ff37443'];嵌套异常是 org.springframework.messaging.MessagingException: 无法在会话上执行;嵌套异常是 org.springframework.core.NestedIOException: Failed to remove file.;嵌套异常是 3: Permission denied, failedMessage=GenericMessage [payload=/REMOTE_FILE_PATH/COMPLETE_FILE_NAME, headers={file_remoteHostPort=127.0.0.1:2222, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@34d7c35d, errorChannel=org. springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@34d7c35d,FILE_NAME = COMPLETE_FILE_NAME,file_remoteDirectory = // sftp_remote,file_originalFile = / REMOTE_FILE_PATH / COMPLETE_FILE_NAME,ID = 2252eee1-6086-c9d9-c421-403f8a0bfc28,file_relativePath = COMPLETE_FILE_NAME,file_remoteFile = COMPLETE_FILE_NAME,时间戳=1588177024991}],headers={id=0d2b19ca-0e7c-7ba8-58cf-f225c126048c,timestamp=1588177025001}] 用于原始 GenericMessage [payload=/REMOTE_FILE_PATH/COMPLETE_FILE_NAME,headers={file_remoteHostPort=127.0.0.1:222] , file_remoteDirectory=//sftp_remote, file_originalFile=/REMOTE_FILE_PATH/COMPLETE_FILE_NAME, id=9f29dd04-362a-ae93-df97-b392572d8864, 文件_relativePath=COMPLETE_FILE_NAME,file_remoteFile=COMPLETE_FILE_NAME,时间戳=1588177023713}]

我不确定我是否做错了事情,或者出站网关不是用于特定的、按需删除的,还是两者兼而有之。希望得到一些帮助。

谢谢!

编辑:

我可以使用 SftpInboundFileSynchronizer.setDeleteRemoteFiles(true) 删除服务器上的文件,因此就 sftp 存储桶而言,我可以删除文件。我是否需要更改 InboundChannelAdapter 中的某些内容?如下:

@Bean
@InboundChannelAdapter(channel = "sftpChannel", poller = @Poller(fixedDelay = "${com.esrx.dhf.listener.sftp.inbound.poll-interval:5000}"))
    public MessageSource<File> sftpMessageSource(SftpInboundProperties properties, JdbcMetadataStore metadataStore) {
        SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
                sftpInboundFileSynchronizer(properties, metadataStore));
        source.setLocalDirectory(new File(System.getProperty("user.dir") + "/" + "sftp_local"));
        source.setAutoCreateLocalDirectory(true);
        source.setMaxFetchSize(1);
        source.setLocalFilter(new FileSystemPersistentAcceptOnceFileListFilter(metadataStore, SFTP_LOCAL_PERSISTENT_PREFIX));
        return source;
    }

编辑:已解决

所以可敬的 Gary Russel 的真正答案是我应该在 SftpOutboundGateway 中指定文件的完整路径。所以现在可行的解决方案意味着新的 OutboundGateway 看起来像这样:

@Bean
@ServiceActivator(inputChannel = "sftpDeleteChannel")
public MessageHandler deleteHandler(SftpInboundProperties properties) {
    return new SftpOutboundGateway(
            sftpSessionFactory(properties),
            "rm", 
            "'" + properties.getRemoteDirectory() + "/'" + " + " + "headers['file_remoteFile']");
    }

【问题讨论】:

    标签: java spring spring-integration spring-integration-sftp


    【解决方案1】:

    你所拥有的是正确的。

    查看原因:

    嵌套异常为 3:权限被拒绝,

    您无权删除该文件。

    【讨论】:

    • 如果这是真的,我错过了什么?当我使用 setDeleteRemoteFiles 读取文件后自动删除文件时,它就像一个魅力。我需要更改传入文件或 InboundChannelAdapter 的内容吗?
    • 经过进一步审查,您似乎正在尝试删除目录"'" + properties.getRemoteDirectory() + "'"。从您的错误内容来看,您似乎需要在该表达式中使用payload。虽然看起来那是一个File 对象;您需要使用远程目录名+“/”+远程文件名来构造文件名。所以"'" + properties.getRemoteDirectory() + "'/'" + "headers['file_remoteFile']"
    • 我无法正确获取表达式的语法。评估时应该看起来像“'/sftp_remote'/'headers['file_remoteFile']”吗?当它这样时,它抱怨声明没有完成。当我添加另一个 ' 时,它表示表达式更多,但已完成评估。我正在玩它。
    • file_remoteFile=COMPLETE_FILE_NAME, timestamp=1588177024991 - it's an SftpFileInfo; so... "'/sftp_remote/' + headers['file_remoteFile'].filename"` .或者您可以使用headers['file_relativePath'],这只是名称。
    • 知道了,谢谢,获胜组合是:"'" + properties.getRemoteDirectory() + "/'" + " + " + "headers['file_remoteFile']"。
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2016-05-31
    • 1970-01-01
    • 2022-11-28
    • 2020-10-28
    • 2014-04-05
    • 1970-01-01
    相关资源
    最近更新 更多