该版本仍在开发中,尚未被视为稳定。对于最新的稳定版本,请使用 Spring Integration 7.0.0spring-doc.cadn.net.cn

SFTP 出站通道适配器

SFTP出站通道适配器是一种特殊产品消息处理器连接到远程目录,并对收到的每个作为入站有效载荷的文件发起文件传输消息. 它还支持多种文件表示方式,确保你不受限制于文件对象。 与FTP出站适配器类似,SFTP出站通道适配器支持以下有效载荷:spring-doc.cadn.net.cn

以下示例展示了如何配置SFTP出站通道适配器:spring-doc.cadn.net.cn

<int-sftp:outbound-channel-adapter id="sftpOutboundAdapter"
    session-factory="sftpSessionFactory"
    channel="inputChannel"
    charset="UTF-8"
    remote-file-separator="/"
    remote-directory="foo/bar"
    remote-filename-generator-expression="payload.getName() + '-mysuffix'"
    filename-generator="fileNameGenerator"
    use-temporary-filename="true"
    chmod="600"
    mode="REPLACE"/>

有关这些属性的详细内容,请参见示范式spring-doc.cadn.net.cn

SpEL与SFTP出站适配器

与 Spring Integration 中的许多组件一样,在配置 SFTP 出站通道适配器时,可以通过指定两个属性来使用 Spring 表达式语言(SpEL):远程目录表达式远程文件名生成器表达式 (前面描述过)。表达式评估上下文以消息为根对象,允许你使用表达式,基于消息中的数据(来自“有效载荷”或“头部”)动态计算文件名或现有目录路径。在前例中,我们定义远程文件名生成器表达式属性中,带有一个表达式值,该表达式基于原始名称计算文件名,同时附加后缀“-mysuffix”。spring-doc.cadn.net.cn

从4.1版本开始,你可以指定模式当你传输文件时。默认情况下,已有文件会被覆盖。模式由以下定义FileExistsMode枚举,包括以下数值:spring-doc.cadn.net.cn

忽视失败文件未被传输。失败导致抛出一个例外,而忽视默默无视转移(尽管调试日志条目会被生成)。spring-doc.cadn.net.cn

4.3 版本引入了CHMOD属性,上传后你可以用它来更改远程文件权限。你可以使用传统的Unix八进制格式(例如,600仅允许文件所有者读写)。使用 Java 配置适配器时,你可以使用setChmodOctal(“600”)setChmod(0600).spring-doc.cadn.net.cn

避免部分写入的文件

处理文件传输时常见的问题之一是处理部分文件的可能性。文件可能在其实际传输完成前就已出现在文件系统中。spring-doc.cadn.net.cn

为解决这个问题,Spring Integration SFTP适配器采用一种通用算法,即文件先以临时名称传输,完全传输后再重命名。spring-doc.cadn.net.cn

默认情况下,所有正在传输的文件都会以附加后缀出现在文件系统中,默认情况下为。写作. 你可以通过设置临时文件后缀属性。spring-doc.cadn.net.cn

不过,在某些情况下你可能不想使用这种方法(例如服务器不允许重命名文件)。遇到这种情况,你可以通过设置来禁用此功能使用临时文件名false(默认为true). 当该属性为false文件以最终名称写入,而消费应用程序需要其他机制来检测文件是否已完全上传,然后才访问。spring-doc.cadn.net.cn

使用 Java 配置配置

以下 Spring Boot 应用程序展示了如何用 Java 配置出站适配器的示例:spring-doc.cadn.net.cn

@SpringBootApplication
@IntegrationComponentScan
public class SftpJavaApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context =
                    new SpringApplicationBuilder(SftpJavaApplication.class)
                        .web(false)
                        .run(args);
        MyGateway gateway = context.getBean(MyGateway.class);
        gateway.sendToSftp(new File("/foo/bar.txt"));
    }

    @Bean
    public SessionFactory<SftpClient.DirEntry> sftpSessionFactory() {
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        factory.setHost("localhost");
        factory.setPort(port);
        factory.setUser("foo");
        factory.setPassword("foo");
        factory.setAllowUnknownKeys(true);
        factory.setTestSession(true);
        return new CachingSessionFactory<SftpClient.DirEntry>(factory);
    }

    @Bean
    @ServiceActivator(inputChannel = "toSftpChannel")
    public MessageHandler handler() {
        SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
        handler.setRemoteDirectoryExpressionString("headers['remote-target-dir']");
        handler.setFileNameGenerator(new FileNameGenerator() {

            @Override
            public String generateFileName(Message<?> message) {
                 return "handlerContent.test";
            }

        });
        return handler;
    }

    @MessagingGateway
    public interface MyGateway {

         @Gateway(requestChannel = "toSftpChannel")
         void sendToSftp(File file);

    }
}

使用 Java DSL 配置

以下 Spring Boot 应用程序展示了如何用 Java DSL 配置出站适配器的示例:spring-doc.cadn.net.cn

@SpringBootApplication
public class SftpJavaApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(SftpJavaApplication.class)
            .web(false)
            .run(args);
    }

    @Bean
    public IntegrationFlow sftpOutboundFlow() {
        return IntegrationFlow.from("toSftpChannel")
            .handle(Sftp.outboundAdapter(this.sftpSessionFactory, FileExistsMode.FAIL)
                         .useTemporaryFileName(false)
                         .remoteDirectory("/foo")
            ).get();
    }

}