此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.1! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.3.1! |
SFTP 出站通道适配器是一个特殊的适配器,它连接到远程目录,并为它作为传入的有效负载接收的每个文件启动文件传输。
它还支持文件的多种表示形式,因此您不限于对象。
与 FTP 出站适配器类似,SFTP 出站通道适配器支持以下有效负载:MessageHandler
Message
File
-
java.io.File
:实际文件对象 -
byte[]
:表示文件内容的字节数组 -
java.lang.String
:表示文件内容的文本 -
java.io.InputStream
:要传输到远程文件的数据流 -
org.springframework.core.io.Resource
:用于传输到远程文件的数据资源
以下示例演示如何配置 SFTP 出站通道适配器:
<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"/>
有关这些属性的更多详细信息,请参阅架构。
SpEL 和 SFTP 出站适配器
与 Spring Integration 中的许多其他组件一样,在配置 SFTP 出站通道适配器时,可以通过指定两个属性来使用 Spring Expression Language (SpEL):和 (如前所述)。
表达式评估上下文将消息作为其根对象,这允许您使用可以根据消息中的数据(来自“有效负载”或“标头”)动态计算文件名或现有目录路径的表达式。
在前面的示例中,我们使用表达式值定义属性,该表达式值根据其原始名称计算文件名,同时附加后缀:“-mysuffix”。remote-directory-expression
remote-filename-generator-expression
remote-filename-generator-expression
从版本 4.1 开始,您可以指定传输文件的时间。
默认情况下,将覆盖现有文件。
模式由枚举定义,枚举包括以下值:mode
FileExistsMode
-
REPLACE
(默认) -
REPLACE_IF_MODIFIED
-
APPEND
-
APPEND_NO_FLUSH
-
IGNORE
-
FAIL
使用 和 时,不会传输文件。 导致引发异常,同时静默地忽略传输(尽管会生成日志条目)。IGNORE
FAIL
FAIL
IGNORE
DEBUG
版本 4.3 引入了该属性,您可以使用该属性在上传后更改远程文件权限。
您可以使用传统的 Unix 八进制格式(例如,仅允许文件所有者进行读写)。
使用 java 配置适配器时,可以使用 或 .chmod
600
setChmodOctal("600")
setChmod(0600)
避免部分写入的文件
处理文件传输时的常见问题之一是处理部分文件的可能性。 文件可能会在传输实际完成之前出现在文件系统中。
为了解决这个问题,Spring Integration SFTP 适配器使用一种通用算法,其中文件以临时名称传输,并在完全传输后重命名。
默认情况下,正在传输的每个文件都会在文件系统中显示一个附加后缀,默认情况下,该后缀为 。
您可以通过设置属性进行更改。.writing
temporary-file-suffix
但是,在某些情况下,您可能不想使用此技术(例如,如果服务器不允许重命名文件)。
对于此类情况,您可以通过设置为(默认值为 )来禁用此功能。
当此属性为 时,文件将以其最终名称写入,并且使用应用程序需要一些其他机制来检测文件是否已完全上传,然后再访问它。use-temporary-file-name
false
true
false
使用 Java 配置进行配置
以下 Spring Boot 应用程序显示了如何使用 Java 配置出站适配器的示例:
@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 配置出站适配器的示例:
@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();
}
}