简体   繁体   English

Spring Integration FTP使用后删除本地文件(Spring Boot)

[英]Spring Integration FTP remove local files after use (Spring Boot)

I am trying to write a program that can take a file from one server via ftp and place it on another server via ftp. 我正在尝试编写一个程序,可以通过ftp从一台服务器获取文件,并通过ftp将其放在另一台服务器上。 However, I am having issues deleting the local file after it has been written. 但是,我在写入后删除本地文件时遇到问题。 Being able to save it locally is not an issue as long as it is temporary. 能够在本地保存它不是问题,只要它是暂时的。 I have tried using an ExpressionEvaluatingRequestHandlerAdvice with an OnSuccessExpression and I could not get it to actually use the expression. 我已经尝试将ExpressionEvaluatingRequestHandlerAdvice与OnSuccessExpression一起使用,我无法让它实际使用该表达式。 The code is here: 代码在这里:

@Configuration
@EnableConfigurationProperties(FTPConnectionProperties.class)
public class FTPConfiguration {

    private FTPConnectionProperties ftpConnectionProperties;

    public FTPConfiguration(FTPConnectionProperties ftpConnectionProperties) {
        this.ftpConnectionProperties = ftpConnectionProperties;
    }

    @Bean
    public SessionFactory<FTPFile> ftpInputSessionFactory() {
        DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
        sf.setHost(ftpConnectionProperties.getInputServer());
        sf.setUsername(ftpConnectionProperties.getInputFtpUser());
        sf.setPassword(ftpConnectionProperties.getInputFtpPassword());
        return new CachingSessionFactory<>(sf);
    }

    @Bean
    public SessionFactory<FTPFile> ftpOutputSessionFactory() {
        DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
        sf.setHost(ftpConnectionProperties.getOutputServer());
        sf.setUsername(ftpConnectionProperties.getOutputFtpUser());
        sf.setPassword(ftpConnectionProperties.getOutputFtpPassword());
        return new CachingSessionFactory<>(sf);
    }

    @Bean
    public FtpInboundFileSynchronizer ftpInboundFileSynchronizer() {
        FtpInboundFileSynchronizer fileSynchronizer = new FtpInboundFileSynchronizer(ftpInputSessionFactory());
        fileSynchronizer.setDeleteRemoteFiles(true);
        fileSynchronizer.setRemoteDirectory(ftpConnectionProperties.getInputDirectory());
        fileSynchronizer.setFilter(new FtpSimplePatternFileListFilter("*.TIF"));
        return fileSynchronizer;
    }

    @Bean
    @InboundChannelAdapter(channel = "input", poller = @Poller(fixedDelay = "5000"))
    public MessageSource<File> ftpMessageSource() {
        FtpInboundFileSynchronizingMessageSource source = new FtpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
        source.setLocalDirectory(new File("ftp-inbound"));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new FileSystemPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), ""));
        return source;
    }

    @Bean
    @ServiceActivator(inputChannel = "input")
    public MessageHandler handler() {
        FtpMessageHandler handler = new FtpMessageHandler(ftpOutputSessionFactory());
        handler.setRemoteDirectoryExpression(new LiteralExpression(ftpConnectionProperties.getOutputDirectory()));
        handler.setFileNameGenerator(message -> {
            if (message.getPayload() instanceof File) {
                return ((File) message.getPayload()).getName();
            } else {
                throw new IllegalArgumentException("File expected as payload.");
            }
        });
        return handler;
    }

}

It is handling the remote files exactly as expected, deleting the remote file from the source and putting into the output, but not removing the local file after use. 它完全按预期处理远程文件,从源中删除远程文件并放入输出,但在使用后不删除本地文件。

I would suggest you to make that input channel as a PublishSubscribeChannel and add one more simple subscriber: 我建议你将该input通道作为PublishSubscribeChannel并添加一个更简单的订阅者:

@Bean
public PublishSubscribeChannel input() {
    return new PublishSubscribeChannel();
}


@Bean
@ServiceActivator(inputChannel = "input")
public MessageHandler handler() {
    ...
}


@Bean
@ServiceActivator(inputChannel = "input")
public MessageHandler deleteLocalFileService() {
    return m ->  ((File) message.getPayload()).delete();
}

This way the same message with the File payload is going to be sent first to your FtpMessageHandler and only after that to this new deleteLocalFileService for removing the local file based on the payload. 这样,带有File有效负载的相同消息将首先发送到您的FtpMessageHandler然后才会发送到这个新的deleteLocalFileService以便根据有效负载删除本地文件。

Simple Solution to fetch file from SFTP server and then move that file to other folder with different name. 简单的解决方案从SFTP服务器获取文件,然后将该文件移动到具有不同名称的其他文件夹。

   @Bean
        public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory() {
            DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);

            if (sftpServerProperties.getSftpPrivateKey() != null) {

                factory.setPrivateKey(sftpServerProperties.getSftpPrivateKey());
                factory.setPrivateKeyPassphrase(sftpServerProperties.getSftpPrivateKeyPassphrase());
            } else {
                factory.setPassword(sftpServerProperties.getPassword());

            }
            factory.setHost(sftpServerProperties.getSftpHost());
            factory.setPort(sftpServerProperties.getSftpPort());
            factory.setUser(sftpServerProperties.getSftpUser());

            factory.setAllowUnknownKeys(true);

            return new CachingSessionFactory<>(factory);
        }

        @Bean
        public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
            SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
            fileSynchronizer.setDeleteRemoteFiles(false);
            fileSynchronizer.setRemoteDirectory(sftpServerProperties.getSftpRemoteDirectoryDownload());
            fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter(sftpServerProperties.getSftpRemoteDirectoryDownloadFilter()));
            return fileSynchronizer;
        }

        @Bean
        @InboundChannelAdapter(channel = "fromSftpChannel", poller = @Poller(cron = "*/10 * * * * *"))
        public MessageSource<File> sftpMessageSource() {
            SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
                    sftpInboundFileSynchronizer());
            source.setLocalDirectory(util.createDirectory(Constants.FILES_DIRECTORY));
            source.setAutoCreateLocalDirectory(true);
            return source;
        }

        @Bean
        @ServiceActivator(inputChannel = "fromSftpChannel")
        public MessageHandler resultFileHandler() {
            return (Message<?> message) -> {
                String csvFilePath = util.getDirectory(Constants.FILES_DIRECTORY) + Constants.INSIDE + message.getHeaders().get("file_name");
                util.readCSVFile(csvFilePath, String.valueOf(message.getHeaders().get("file_name")));
                File file = (File) message.getPayload();
                File newFile = new File(file.getPath() + System.currentTimeMillis());

                try {
                    FileUtils.copyFile(file, newFile);
                    sftpGateway.sendToSftp(newFile);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (file.exists()) {
                    file.delete();
                }
                if (newFile.exists()) {
                    newFile.delete();
                }

            };
        }

        @Bean
        @ServiceActivator(inputChannel = "toSftpChannelDest")
        public MessageHandler handlerOrderBackUp() {
            SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
            handler.setAutoCreateDirectory(true);
            handler.setRemoteDirectoryExpression(new LiteralExpression(sftpServerProperties.getSftpRemoteBackupDirectory()));
            return handler;
        }


        @MessagingGateway
        public interface SFTPGateway {
            @Gateway(requestChannel = "toSftpChannelDest")
            void sendToSftp(File file);


        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM