本篇博文介绍spring integration sftp技术中的sftp outbound gateway相关内容。Sftp outbound gateway 其实质就是提供一组命令(如图1)来实现对服务器上文件的交互操作,包括文件的获取(文件对象和文件名等)、上传(单文件和多文件)、下载(单文件和多文件),删除,移动。具体在开发的过程中可以使用多种配置方式如xml,springboot等。本文在介绍SFTP Outbound Gateway 的基础上,使用SpringBoot开发框架进行相应的开发实践。
该命令的功能是获取远程文件,包括文件对象和文件路径名称等,具体返回值根据配置的选项:
除此之外,还可以配置文件名过滤器等;
命令返回值: 通过ls命令获取的message payload,是一组文件名或者FileInfo对象,对象中提供了有关文件的修改时间,权限以及其他的信息;
ls命令作用的远程文件夹,由header头的file_remoteDirectory属性提供;
建议提醒:如果使用-R递归选择项,文件名将含有子文件夹,表明递归文件的相对路径;如果使用-dirs选项,每一个递归的子文件夹,返回的元素中将含有子文件夹名;在这种情况下,建议不用使用-1罗列文件名,因为返回的元素中不能够区分是文件还是文件夹?建议返回FileInfo对象。
下面是开发示例:
@Bean
@ServiceActivator(inputChannel = "sftpChannel2")
public MessageHandler handler2() {
//指定session配置和命令
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpSessionFactory(),"ls","payload");
sftpOutboundGateway.setOptions("-dirs"); //配置项
return sftpOutboundGateway;
}
//使用Gateway触发
@MessagingGateway
public interface MessageGateway {
@Gateway(requestChannel = "sftpChannel2")
List<FileInfo> listFileName(String dir); //指定远程文件夹
}
该命令提供检索远程文件名的功能,相当于ls -1的命令;支持如下配置:
返回值:通过nlst获取的文件message payload,就是一组文件名列表;
该命令由于获取一个远程的文件,支持如下的选项:
file_remoteDirectory 头包含了文件的远程路径,file_remoteFile属性为文件名;
返回值:使用get方法获取的message的payload是一个File对象,如果使用-straem,则payload就是一个InputStream文件流。
对于文本文件,有个通用的案例,使用file splitter 或 stream transformer。当以文件流的形式获取远程文件,Session在结束之后要及时关闭. Session由closeableResource属性header头文件,IntegrationMessageHeaderAccessor提供了流资源的关闭操作。
该命令用来基于特定的文件模式过滤器获取多个文件,支持如下的设置:
message payload返回的是List< >对象,集合元素是File。
注意:
在5.0版本之后,若FileExistsMode=IGNORE,payload不再包含已经存在的文件对象。
remote path的表达式应该是以结尾,类似myfiles/,表示获取完整的文件夹树myfiles;
注意,在版本5.0之后,MGET命令可以设置FileExistsMode.REPLACE_IF_MODIFIED模式,去同步整个文件夹,被修改的文件的时间戳也会相应修改。不用关心-P模式;
-R模式,默认情况下是整个文件夹,同时也支持设置文件或文件夹过滤器FileListFilter; 该过滤器提供两种方式filename-pattern或者filename-regex属性;例如filename-regex="(subDir|.*1.txt)" 获取subDir下所有以1.txt结尾的文件;
通常,将在local-directory-expression中使用#remoteDirectory变量,以便远程目录结构在本地保留。
下面是开发示例:
@Bean
@ServiceActivator(inputChannel = "sftpChannel3")
public MessageHandler handler3() {
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpSessionFactory(),"mget","payload");
sftpOutboundGateway.setOptions("-R");
sftpOutboundGateway.setFileExistsMode(FileExistsMode.REPLACE_IF_MODIFIED);
sftpOutboundGateway.setLocalDirectory(new File("E:\\sftp_tmp_dir"));
sftpOutboundGateway.setAutoCreateLocalDirectory(true);
return sftpOutboundGateway;
}
@MessagingGateway
public interface MessageGateway {
@Gateway(requestChannel = "sftpChannel3")
List<File> listFile(String dir);
}
该命令是发送单个文件到远程服务器;
message的payload可以是File对象,byte[]数组,或者字符串;
remote-filename-generator用来命名远程文件。其他的属性如remote-directory,temporary-remote-directory等等;
返回值:put命令的message的payload的返回值是string,包含文件传输后在服务器上的整个路径;
该命令是发送多个文件到服务器,支持如下配置:
message payload必须是文件或者文件路径字符串,代表了本地文件夹;自版本5.1之后,也支持文件或者路径字符串集合;
put的配置,同样适合mput,同时除此之外,还提供过滤文件的mput-pattern,mput-regex,mput-filter等;
版本4.3之后,支持设置文件的权限;
返回值:mput执行之后的返回值,是一个List,包含文件转移之后的路径集合。
下面是开发示例:
//!important,put命令需要借助与sftpRemoteFileTemplate。
//看源码,可以发现outbound gateway 有多种构造函数;
@Bean
@ServiceActivator(inputChannel = "sftpChannel4")
public MessageHandler handler4(){
SftpRemoteFileTemplate sftpRemoteFileTemplate = new SftpRemoteFileTemplate(sftpSessionFactory());
sftpRemoteFileTemplate.setRemoteDirectoryExpression(new LiteralExpression("/send"));
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpRemoteFileTemplate,"put","payload");
sftpOutboundGateway.setBeanFactory(beanFactory);
return sftpOutboundGateway;
}
@Bean
@ServiceActivator(inputChannel = "sftpChannel5")
public MessageHandler handler5(){
SftpRemoteFileTemplate sftpRemoteFileTemplate = new SftpRemoteFileTemplate(sftpSessionFactory());
sftpRemoteFileTemplate.setRemoteDirectoryExpression(new LiteralExpression("/send"));
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpRemoteFileTemplate,"mput","payload");
//配置过滤器
sftpOutboundGateway.setMputFilter(new FileListFilter<File>() {
@Override
public List<File> filterFiles(File[] files) {
if(...){
...
}
return null;
}
});
sftpOutboundGateway.setBeanFactory(beanFactory);
return sftpOutboundGateway;
}
该命令是删除远程文件。
如果删除成功,message payload的返回值是Boolean.TRUE;否则是Boolean.FALSE。
file_remoteDirectory头包含远程文件属性;
下面是开发示例:
@Bean
@ServiceActivator(inputChannel = "sftpChannel6")
public MessageHandler handler6(){
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpSessionFactory(),"rm","payload");
sftpOutboundGateway.setBeanFactory(beanFactory);
return sftpOutboundGateway;
}
该命令是移动文件在远程服务器上的位置。
返回值:转移成功,返回true,否则是false;
下面是开发示例:
@Bean
@ServiceActivator(inputChannel = "sftpChannel7")
public MessageHandler handler7(){
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpSessionFactory(),"mv","'send/22.TXT'");
sftpOutboundGateway.setRenameExpression(new LiteralExpression("send1/22.TXT"));
sftpOutboundGateway.setBeanFactory(beanFactory);
return sftpOutboundGateway;
}
本文代码上传到github仓库。https://github.com/XiaoHuarong/SpringIntegrationExamples.git