spring integration sftp

spring integration sftp

spring integration sftp 操作 sftp


spring integration

spring integration 是 spring 家族中的一个企业系统整合框架。

其集成了 spring 中的轻量级消息传递,并支持通过声明性适配器与外部系统集成。其主要目标是为企业集成提供一个简单的模型,同时保持关注点的分离。

其特性包括:

  • 多企业集成模式的实现
  • 端点
  • 通道(点对点和发布/订阅)
  • 聚合器
  • 过滤器
  • 转换器
  • 控制总线
  • 与外部系统集成
  • ReST/HTTP
  • FTP/SFTP
  • STOMP
  • WebServices(SOAP and Rest)
  • TCP/UDP
  • JMS
  • RabbitMQ
  • Email
  • 此框架具有广泛的 JMX 支持
  • 将框架组件公开为 MBean
  • 用于从 MBean 获取属性、调用操作、发送/接收的适配器

spring integration sftp

spring integration sftp 是 spring integration 框架中支持 sftp 的模块。

spring integration 提供了三种方式来支持对 sftp 的操作,分别是:

  • Inbound Channel Adapter: 入站通道适配器
  • Outbound Channel Adapter: 出站通道适配器
  • Outbound Gateway: 出站网关

其底层依赖于 com.jcraft.jsch,即 linux 链接并执行命令的工具包。

核心组件

  • SftpSessionFactory:
    sftp 客户端与服务端的会话工厂。客户端每次访问服务器时都会创建一个 session 对象,且可以通过 SftpSessionCaching 将 session 对象缓存起来,支持 session 共享,即可以在一个会话上进行多个 channel 的操作。如果 session 被重置,则在最后一次 channel 关闭之后,将断开连接。isSharedSession 为 true 时 session 将共享。
  • SftpSessionCaching:
    sftp 会话缓存工厂。通过 poolSize 和 sessionWaiteTimeout 来设置缓存池大小和会话等待超时时间。缓存池默认是无限大,超时时间默认是 Integer.MAX_VALUE。
  • SftpRemoteFileTemplate:
    基于 SftpSessionFactory 创建的 sftp 文件操作模板类。其父类是 RemoteFileTemplate。支持上传、下载、追加、删除、重命名、列表、是否存在。基于输入输出流实现。
  • SftpInboundChannelAdapter:
    sftp 入站通道适配器。可同步远程目录到本地,且可监听远程文件的操作,可实现下载。
  • SftpOutboundChannelAdapter:
    sftp 出站通道适配器。实际是一个 sftp 消息处理器,将在服务器与客户端之间创建一个消息传输通道。此处的消息指的是 Message 的 payload,其支持 File、byte[]、String。其支持 ls、nlst、get、rm、mget、mv、put、mput 操作。
  • Channel Adapter:
    通道适配器,实际上是适配消息在客户端和服务器之间的传输。inbound adapter 是接收其它系统的消息,outbound adapter 是发送消息到其它系统。
  • @ServiceActivator:
    将注解作用的方法注册为处理消息的站点,inputChannel 表示接收消息的通道。

操作 sftp 命令及参数

命令:
	ls: 获取文件列表
	nlst: 获取列表内的文件名
	get: 下载单个文件
	rm: 删除文件
	mget: 批量下载
	mv: 移动/重命名文件
    put: 上传单个文件
    mput: 批量上传
可配参数:
    -1: 在 ls 的结果中只返回文件名,不返回文件信息
    -a: 在 ls 中返回所有文件(隐藏文件也会返回)
    -f: 对 ls 的结果不排序(fileName)
    -dirs: 在 ls 的结果中返回目录信息
    -links: 在 ls 的结果中返回文件详细信息(权限、形态、大小等)
    -P: get、mget(下载)时将远程文件时间信息同步到本地
    -x: get、mget(下载)时如果没有文件返回将抛出一个异常
    -R: ls、mget 时递归文件夹
    -stream: get 时返回文件流 且必须调用 Session.close()
    -D: get、mget 成功后删除远程文件

springboot + spring integration sftp demo

version:

springboot: 2.5.6
spring integration: 5.5.5
spring inetgration sftp: 5.5.5

pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-integration</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-sftp</artifactId>
</dependency>

SftpConfig:

sftp 配置工厂及消息处理器。

@Configuration
@EnableIntegration   // 开启整合
public class SftpConfig {

    private static final Logger logger = LogManager.getLogger(SftpConfig.class);

    /**
     * SftpSessionFactory
     * sftp 客户端与服务端的会话工厂
     *
     * SftpSessionCaching
     * sftp 会话缓存工厂
     *
     * @return
     */
    @Bean
    public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory() {
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        factory.setHost("ip");
        factory.setPort(22);
        factory.setUser("momo");
        factory.setPassword("momo");
        factory.setAllowUnknownKeys(true);   // 允许无条件连接

        CachingSessionFactory<ChannelSftp.LsEntry> cachingSessionFactory = new CachingSessionFactory<>(factory);
        cachingSessionFactory.setPoolSize(10);
        cachingSessionFactory.setSessionWaitTimeout(10 * 1000);
        return cachingSessionFactory;
    }

    /**
     * SftpRemoteFileTemplate
     * 于 SftpSessionFactory 创建的 sftp 文件操作模板类
     * 用来创建 SftpOutboundGateway(见 SftpOutboundGateway 构造方法源码)
     *
     * @return
     */
    @Bean
    public SftpRemoteFileTemplate sftpRemoteFileTemplate() {
        return new SftpRemoteFileTemplate(sftpSessionFactory());
    }

    /**
     * 发送执行 ls 命令
     * payload 为远程目录
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "lsChannel")
    public MessageHandler lsHandler() {
        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "ls", "payload");
        gateway.setOptions("-dirs");   // 显示目录记录
        return gateway;
    }

    /**
     * 发送执行 nlst 命令
     * payload 为远程目录
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "nlstChannel")
    public MessageHandler nlstHandler() {
        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "nlst", "payload");
        gateway.setOptions("-f");
        return gateway;
    }

    /**
     * 发送执行 get 命令
     * payload 为远程文件
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "getChannel")
    public MessageHandler getHandler() {
        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "get", "payload");
        gateway.setOptions("-P");
        gateway.setLocalDirectory(new File("D:\\xgllhz\\tmp\\sftp"));
        return gateway;
    }

    /**
     * 发送执行 rm 命令
     * payload 为远程文件
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "rmChannel")
    public MessageHandler rmHandler() {
        return new SftpOutboundGateway(sftpSessionFactory(), "rm", "payload");
    }

    /**
     * 发送执行 mget 命令
     * payload 为远程目录
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "mgetChannel")
    public MessageHandler mgetHandler() {
        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "mget", "payload");
        gateway.setOptions("-R");
        gateway.setFileExistsMode(FileExistsMode.REPLACE_IF_MODIFIED);   // 若被修改则替换
        gateway.setLocalDirectory(new File("D:\\xgllhz\\tmp\\sftp"));
        gateway.setAutoCreateLocalDirectory(true);   // 自动创建本地目录
        return gateway;
    }

    /**
     * 发送执行 mv 命令
     * payload 为远程文件
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "mvChannel")
    public MessageHandler mvHandler() {
        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "mv", "payload");
        gateway.setRenameExpression(new LiteralExpression("sftp/tests/test.txt"));
        return gateway;
    }

    /**
     * 发送执行 put 命令
     * payload 为 File
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "putChannel")
    public MessageHandler putHandler() {
        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "put", "payload");
        gateway.setRemoteDirectoryExpression(new LiteralExpression("sftp/test/"));
        return gateway;
    }

    /**
     * 发送执行 mput 命令
     * payload 为 List< File>
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "mputChannel")
    public MessageHandler mputHandler() {
        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "mput", "payload");
        gateway.setOptions("-R");
        gateway.setRemoteDirectoryExpression(new LiteralExpression("sftp/test/"));   // 设置远程目录
        gateway.setAutoCreateDirectory(true);   // 自动创建远程目录
        return gateway;
    }

}

SftpGateway:

@MessagingGateway 用于消息网关代理整合,requestChannel 表示发送消息的通道。

@MessagingGateway
public interface SftpGateway {

    /**
     * 获取远程指定目录下文件列表
     * @param directory 远程目录
     * @return List<SftpFileInfo>
     */
    @Gateway(requestChannel = "lsChannel")
    List<SftpFileInfo> listFile(String directory);

    /**
     * 获取远程指定目录下所有文件名
     * @param directory 远程目录
     * @return List<String>
     */
    @Gateway(requestChannel = "nlstChannel")
    List<String> nlstFile(String directory);

    /**
     * 下载指定文件
     * @param directory 远程文件名(包含目录)
     * @return File
     */
    @Gateway(requestChannel = "getChannel")
    File getFile(String directory);

    /**
     * 删除远程指定文件
     * @param directory 远程文件名(包含目录)
     * @return boolean
     */
    @Gateway(requestChannel = "rmChannel")
    Boolean rmFile(String directory);

    /**
     * 批量下载远程指定目录下所有文件
     * @param directory 远程目录
     * @return List<File>
     */
    @Gateway(requestChannel = "mgetChannel")
    List<File> mgetFile(String directory);

    /**
     * 移动远程指定文件
     * @param directory 远程文件名(包含目录)
     * @return boolean
     */
    @Gateway(requestChannel = "mvChannel")
    Boolean mvFile(String directory);

    /**
     * 上传本地文件
     * @param file File
     * @return String 远程文件名(包含目录)
     */
    @Gateway(requestChannel = "putChannel")
    String putFile(File file);

    /**
     * 批量上传本地文件
     * @param list List<File>
     * @return List<String> 远程文件名(包含目录)
     */
    @Gateway(requestChannel = "mputChannel")
    List<String> mputFile(List<File> list);

}

TestController:

@RestController
@RequestMapping("/api/common")
public class TestController {

    private static final Logger logger = LogManager.getLogger(TestController.class);

    @Resource
    private SftpGateway sftpGateway;

    @RequestMapping("/sftp")
    @ResponseBody
    public APIResponse<Map<String, Object>> sftp() {
        logger.info("enter TestController.sftp()");

        // ls
        List<SftpFileInfo> list1 = sftpGateway.listFile("/sftp/test/");
        list1.stream().peek(fileInfo -> System.out.println(fileInfo.getFilename()));

        // nlst
        List<String> list2 = sftpGateway.nlstFile("/sftp/test/");
        System.out.println(list2.toString());

        // get
        File file = sftpGateway.getFile("/sftp/test/test.txt");
        System.out.println(file.getName());

        // rm
        boolean res1 = sftpGateway.rmFile("/sftp/test/test.txt");
        System.out.println(res1);

        // mget
        List<File> list3 = sftpGateway.mgetFile("/sftp/test/");
        list3.stream().peek(file -> System.out.println(file.getName()));

        // mv
        boolean res2 = sftpGateway.mvFile("/sftp/test/test.txt");
        System.out.println(res2);
        
        // put
        File file2 = new File("D:\\xgllhz\\tmp\\sftp\\test.txt");
        String fileName = sftpGateway.putFile(file);
        System.out.println(fileName);

        // mput
        List<File> list4 = new ArrayList<>();
        list4.add(new File("D:\\xgllhz\\tmp\\sftp\\test1.txt"));
        list4.add(new File("D:\\xgllhz\\tmp\\sftp\\test2.txt"));
        list4.add(new File("D:\\xgllhz\\tmp\\sftp\\test3.txt"));
        List<String> lists = sftpGateway.mputFile(list4);
        lists.forEach(System.out::println);

        return new APIResponse<>();
    }
}

@XGLLHZ-一路生花.mp3

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值