Spring Integration sftp 技术之 SFTP Outbound Gateway

本篇博文介绍spring integration sftp技术中的sftp outbound gateway相关内容。Sftp outbound gateway 其实质就是提供一组命令(如图1)来实现对服务器上文件的交互操作,包括文件的获取(文件对象和文件名等)、上传(单文件和多文件)、下载(单文件和多文件),删除,移动。具体在开发的过程中可以使用多种配置方式如xml,springboot等。本文在介绍SFTP Outbound Gateway 的基础上,使用SpringBoot开发框架进行相应的开发实践。

1. 命令组Spring Integration sftp 技术之 SFTP Outbound Gateway_第1张图片
1.1 ls

该命令的功能是获取远程文件,包括文件对象和文件路径名称等,具体返回值根据配置的选项:

  • -1 :获取一组远程文件的文件名;默认是获取一组FileInfo对象;
  • -a:获取所有的文件(包括开始的文件,递归时使用);
  • - f:检索结果不用排序;
  • -dirs: 包括文件夹,默认是包括的;
  • -links:包括链接符号,默认是包括的;
  • -R:递归方式获取远程文件夹下所有文件,默认不递归的。

除此之外,还可以配置文件名过滤器等;
命令返回值: 通过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); //指定远程文件夹
 }
1.2 nlst

该命令提供检索远程文件名的功能,相当于ls -1的命令;支持如下配置:

  • -f:文件名不排序;
    nlst命令作用的远程文件夹,由header头的file_remoteDirectory提供。

返回值:通过nlst获取的文件message payload,就是一组文件名列表;

1.3 get

该命令由于获取一个远程的文件,支持如下的选项:

  • -P:文件下载之后,保持文件在本地的时间戳同远程服务器一致;
  • -stream:以流的方式获取远程文件;
  • -D:文件成功转移之后,删除远程文件;如果FileExistsMode设置为IGNORE,远程文件不会删除。

file_remoteDirectory 头包含了文件的远程路径,file_remoteFile属性为文件名;

返回值:使用get方法获取的message的payload是一个File对象,如果使用-straem,则payload就是一个InputStream文件流。

对于文本文件,有个通用的案例,使用file splitter 或 stream transformer。当以文件流的形式获取远程文件,Session在结束之后要及时关闭. Session由closeableResource属性header头文件,IntegrationMessageHeaderAccessor提供了流资源的关闭操作。

1.4 mget

该命令用来基于特定的文件模式过滤器获取多个文件,支持如下的设置:

  • -P:保留远程文件的时间戳;
  • -R:递归下载所有符合的文件;
  • -x:没有文件匹配文件筛选模式,抛出异常,并返回空集合;
  • -D:文件成功转移之后。如何FileExistsMode=IGNORE,本地文件存在,文件不会删除;

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);
}
1.5 put

该命令是发送单个文件到远程服务器;
message的payload可以是File对象,byte[]数组,或者字符串;
remote-filename-generator用来命名远程文件。其他的属性如remote-directory,temporary-remote-directory等等;
返回值:put命令的message的payload的返回值是string,包含文件传输后在服务器上的整个路径;

1.5 mput

该命令是发送多个文件到服务器,支持如下配置:

  • -R: 递归发送文件和子文件夹下的所有文件;

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;
    }
1.6 rm

该命令是删除远程文件。
如果删除成功,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;
}
1.7 mv

该命令是移动文件在远程服务器上的位置。
返回值:转移成功,返回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

你可能感兴趣的:(Spring,Integration)