[英]Copy and move a file from SFTP using Java config in Spring Integration
I am new to Spring integration.我是 Spring 集成的新手。 I've this requirement to first move a file from /files folder to /process folder in SFTP location and then copy that file to local.
我有这个要求,首先将文件从 /files 文件夹移动到 SFTP 位置的 /process 文件夹,然后将该文件复制到本地。 I am suggested to use gateway and configuration has to be in java using annotations.
建议我使用网关,并且必须使用注释在 java 中进行配置。 I have tried seeking for answers here on stackoverflow but couldn't find something relevant.
我曾尝试在 stackoverflow 上寻找答案,但找不到相关内容。 However I was able to copy the file using @InboundChannelAdapter and by configuring other beans.
但是,我能够使用 @InboundChannelAdapter 并通过配置其他 bean 来复制文件。
Below is the code I have written so far下面是我到目前为止编写的代码
Configuration public class SftpConfiguration {配置公共类 SftpConfiguration {
@Value("${ftp.file.host}")
private String host;
@Value("${ftp.file.port")
private int port;
@Value("${ftp.file.user")
private String user;
@Value("${ftp.file.password")
private String password;
@Value("${directorry.file.remote")
private String remoteDir;
@Value("${directorry.file.in.pollerDelay")
final private String pollerDelay = "1000";
@Value("${directory.file.remote.move}")
private String toMoveDirectory;
@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(host);
factory.setPort(port);
factory.setUser(user);
factory.setPassword(password);
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<LsEntry>(factory);
}
@Bean
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(false);
fileSynchronizer.setRemoteDirectory(remoteDir);
fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.xlsx"));
return fileSynchronizer;
}
@Bean
@InboundChannelAdapter(channel = "sftpChannel", poller = @Poller(fixedDelay = pollerDelay))
public MessageSource<File> sftpMessageSource() {
SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
sftpInboundFileSynchronizer());
source.setLocalDirectory(new File("ftp-inbound"));
source.setAutoCreateLocalDirectory(true);
source.setLocalFilter(new AcceptOnceFileListFilter<File>());
return source;
}
@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler() {
return new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
try {
new FtpOrderRequestHandler().handle((File) message.getPayload());
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handlerOut() {
return new SftpOutboundGateway(sftpSessionFactory(), "mv", toMoveDirectory);
}
} }
I will appreciate any tips or suggestion .我将不胜感激任何提示或建议。 Thanks.
谢谢。
Right, you need to use @Bean
with the @InboundChannelAdapter
for the SftpInboundFileSynchronizingMessageSource
to download files from the remote /process
folder to local directory.对,您需要将
@Bean
与@InboundChannelAdapter
用于SftpInboundFileSynchronizingMessageSource
以将文件从远程/process
文件夹下载到本地目录。 This is done on the poller basis and is a separate process, fully not related to the move operation.这是在轮询器的基础上完成的,是一个单独的过程,与移动操作完全无关。 That move logic you can perform via
FtpOutboundGateway
with the MV
command:您可以使用
MV
命令通过FtpOutboundGateway
执行该移动逻辑:
The mv command has no options.
mv命令没有选项。
The expression attribute defines the "from" path and the rename-expression attribute defines the "to" path.
expression属性定义“from”路径, rename-expression属性定义“to”路径。 By default, the rename-expression is
headers['file_renameTo']
.默认情况下,重命名表达式是
headers['file_renameTo']
。 This expression must not evaluate to null, or an emptyString
.此表达式的计算结果不得为 null 或空
String
。 If necessary, any remote directories needed will be created.如有必要,将创建所需的任何远程目录。 The payload of the result message is
Boolean.TRUE
.结果消息的负载是
Boolean.TRUE
。 The original remote directory is provided in thefile_remoteDirectory
header, and the filename is provided in thefile_remoteFile
header.原始远程目录在
file_remoteDirectory
标头中提供,文件名在file_remoteFile
标头中提供。 The new path is in thefile_renameTo
header.新路径位于
file_renameTo
标头中。
This one you have to use via:这个你必须通过以下方式使用:
@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler() {
return new SftpOutboundGateway(ftpSessionFactory(), "mv", "'my_remote_dir/my_file'");
}
I tried and the following worked for me.我试过了,以下对我有用。
@Configuration
@EnableIntegration
public class SftpConfiguration {
@Value("${config.adapter.ftp.host}")
private String host;
@Value("${config.adapter.ftp.port}")
private int port;
@Value("${config.adapter.ftp.user}")
private String user;
@Value("${config.adapter.ftp.password}")
private String password;
@Autowired
private FtpOrderRequestHandler handler;
@Autowired
ConfigurableApplicationContext context;
@Value("${config.adapter.ftp.excel.sourceFolder}")
private String sourceDir;
@Value("${config.adapter.ftp.excel.localFolder}")
private String localDir;
@Value("${config.adapter.ftp.excel.backupFolder}")
private String backupDir;
@Value("${config.adapter.ftp.statusExcel.destinationFolder}")
private String statusDest;
private static final Logger LOGGER = LoggerFactory.getLogger(SftpConfiguration.class);
@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(host);
factory.setPort(port);
factory.setUser(user);
factory.setPassword(password);
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<LsEntry>(factory);
}
@Bean
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(true);
fileSynchronizer.setRemoteDirectory(sourceDir);
fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.xlsx"));
return fileSynchronizer;
}
@Bean
@InboundChannelAdapter(channel = "sftpChannel", poller = @Poller(cron = "${config.cron.cataligent.order}"), autoStartup = "true")
public MessageSource<File> sftpMessageSource() {
SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
sftpInboundFileSynchronizer());
source.setLocalDirectory(new File(localDir));
source.setAutoCreateLocalDirectory(true);
source.setLocalFilter(new AcceptOnceFileListFilter<File>());
return source;
}
@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handlerOrder() {
return new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
try {
SFTPGateway gateway = context.getBean(SFTPGateway.class);
final File orderFile = (File) message.getPayload();
gateway.sendToSftp(orderFile);
LOGGER.debug("{} is picked by scheduler and moved to {} folder",orderFile.getName(),backupDir);
handler.handle((File) message.getPayload());
handler.deleteFileFromLocal((File) message.getPayload());
LOGGER.info("Processing of file {} is completed",orderFile.getName());
} catch (IOException e) {
LOGGER.error("Error occurred while processing order file exception is {}",e.getMessage());
}
}
};
}
@Bean
@ServiceActivator(inputChannel = "sftpChannelDest")
public MessageHandler handlerOrderBackUp() {
SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
handler.setRemoteDirectoryExpression(new LiteralExpression(backupDir));
return handler;
}
@Bean
@ServiceActivator(inputChannel = "sftpChannelStatus")
public MessageHandler handlerOrderStatusUS() {
SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
handler.setRemoteDirectoryExpression(new LiteralExpression(statusDest));
return handler;
}
@MessagingGateway
public interface SFTPGateway {
@Gateway(requestChannel = "sftpChannelDest")
void sendToSftp(File file);
@Gateway(requestChannel = "sftpChannelStatus")
void sendToSftpOrderStatus(File file);
}
}
I have used this for picking up a file from SFTP location.我用它来从 SFTP 位置获取文件。 Saving it at local.
保存在本地。 Then moving the file to backup folder and then processing the whole file.
然后将文件移动到备份文件夹,然后处理整个文件。 After processing deleted the file from the local.
处理后从本地删除文件。
I have used gateway(@MessagingGateway) for file movement and I have two different methods in that interface.我已经使用网关(@MessagingGateway)进行文件移动,并且在该界面中有两种不同的方法。 One for moving the same file to backup folder and other method is to move another file(a status file) in my code to desired SFTP location.
将同一文件移动到备份文件夹的一种方法是将代码中的另一个文件(状态文件)移动到所需的 SFTP 位置。 I've tried to keep the code clean for better understanding.
我试图保持代码干净以便更好地理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.