FTP 送信チャネルアダプター
FTP 発信チャネルアダプターは、FTP サーバーに接続し、受信メッセージのペイロードで受信するすべてのファイルに対して FTP 転送を開始する MessageHandler 実装に依存しています。また、ファイルのいくつかの表現もサポートしているため、java.io.File -typed ペイロードのみに制限されません。FTP 発信チャネルアダプターは、次のペイロードをサポートしています。
java.io.File: 実際のファイルオブジェクトbyte[]: ファイルの内容を表すバイト配列java.lang.String: ファイルの内容を表すテキストjava.io.InputStream: リモートファイルに転送するデータのストリームorg.springframework.core.io.Resource: リモートファイルに転送するデータのリソース
次の例は、outbound-channel-adapter を構成する方法を示しています。
<int-ftp:outbound-channel-adapter id="ftpOutbound"
channel="ftpChannel"
session-factory="ftpSessionFactory"
charset="UTF-8"
remote-file-separator="/"
auto-create-directory="true"
remote-directory-expression="headers['remote_dir']"
temporary-remote-directory-expression="headers['temp_remote_dir']"
filename-generator="fileNameGenerator"
use-temporary-filename="true"
chmod="600"
mode="REPLACE"/> 上記の構成は、filename-generator (o.s.i.file.FileNameGenerator 戦略インターフェースの実装)、session-factory への参照、その他の属性などのさまざまな属性の値を提供しながら、outbound-channel-adapter エレメントを使用して FTP 送信・チャネルアダプターを構成する方法を示しています。また、SpEL を使用して remote-directory-expression、temporary-remote-directory-expression、remote-filename-generator-expression (前の例に示した filename-generator の代替 SpEL)などの設定を構成できる *expression 属性の例もいくつか見ることができます。SpEL の使用を許可する他のコンポーネントと同様に、ペイロードとメッセージヘッダーへのアクセスは、「ペイロード」変数と「ヘッダー」変数を介して利用できます。使用可能な属性の詳細については、スキーマ [GitHub] (英語) を参照してください。
デフォルトでは、ファイル名ジェネレーターが指定されていない場合、Spring Integration は o.s.i.file.DefaultFileNameGenerator を使用します。DefaultFileNameGenerator は、MessageHeaders の file_name ヘッダー(存在する場合)の値に基づいてファイル名を決定します。または、メッセージのペイロードがすでに java.io.File である場合、そのファイルの元の名前を使用します。 |
特定の値(remote-directory など)の定義は、プラットフォームまたは FTP サーバーに依存する場合があります。例: forum.spring.io/showthread.php?p=333478&posted=1#post333478 (英語) で報告されたように、一部のプラットフォームでは、ディレクトリ定義の最後にスラッシュを追加する必要があります(たとえば、remote-directory="/thing1/thing2" の代わりに remote-directory="/thing1/thing2/")。 |
バージョン 4.1 以降、ファイルの転送時に mode を指定できます。デフォルトでは、既存のファイルは上書きされます。モードは FileExistsMode 列挙によって定義され、次の値が含まれます。
REPLACE(default)REPLACE_IF_MODIFIEDAPPENDAPPEND_NO_FLUSHIGNOREFAIL
IGNORE および FAIL はファイルを転送しません。FAIL は例外をスローしますが、IGNORE はサイレントに転送を無視します(ただし、DEBUG ログエントリが生成されます)。
バージョン 5.2 では、chmod 属性が導入されました。これを使用すると、アップロード後にリモートファイルのパーミッションを変更できます。従来の Unix 8 進形式を使用できます(たとえば、600 はファイル所有者のみに読み取り / 書き込みを許可します)。java を使用してアダプターを設定する場合は、setChmodOctal("600") または setChmod(0600) を使用できます。FTP サーバーが SITE CHMOD サブコマンドをサポートしている場合にのみ適用されます。
部分的に書き込まれたファイルの回避
ファイル転送を処理するときに発生する一般的な問題の 1 つは、部分的なファイルを処理する可能性です。つまり、転送が実際に完了する前にファイルがファイルシステムに表示される場合があります。
この課題に対処するために、Spring Integration FTP アダプターは一般的なアルゴリズムを使用します。ファイルは一時的な名前で転送され、完全に転送されると名前が変更されます。
デフォルトでは、転送中のすべてのファイルは、追加のサフィックス(デフォルトでは .writing)とともにファイルシステムに表示されます。temporary-file-suffix 属性を設定することにより、このサフィックスを変更できます。
ただし、サーバーがファイル名の変更を許可していない場合など、この手法を使用したくない状況もあります。このような状況では、use-temporary-file-name を false に設定することでこの機能を無効にすることができます(デフォルトは true です)。この属性が false の場合、ファイルは最終的な名前で書き込まれるため、ファイルにアクセスするアプリケーションは、ファイルが完全にアップロードされたことを検出するための別のメカニズムが必要になります。
Java 構成を使用した構成
次の Spring Boot アプリケーションは、Java 構成で送信アダプターを構成する方法の例を示しています。
@SpringBootApplication
@IntegrationComponentScan
public class FtpJavaApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new SpringApplicationBuilder(FtpJavaApplication.class)
.web(false)
.run(args);
MyGateway gateway = context.getBean(MyGateway.class);
gateway.sendToFtp(new File("/foo/bar.txt"));
}
@Bean
public SessionFactory<FTPFile> ftpSessionFactory() {
DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
sf.setHost("localhost");
sf.setPort(port);
sf.setUsername("foo");
sf.setPassword("foo");
sf.setTestSession(true);
return new CachingSessionFactory<FTPFile>(sf);
}
@Bean
@ServiceActivator(inputChannel = "ftpChannel")
public MessageHandler handler() {
FtpMessageHandler handler = new FtpMessageHandler(ftpSessionFactory());
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 = "toFtpChannel")
void sendToFtp(File file);
}
}Java DSL を使用した構成
次の Spring Boot アプリケーションは、Java DSL を使用して送信アダプターを構成する方法の例を示しています。
@SpringBootApplication
@IntegrationComponentScan
public class FtpJavaApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new SpringApplicationBuilder(FtpJavaApplication.class)
.web(false)
.run(args);
MyGateway gateway = context.getBean(MyGateway.class);
gateway.sendToFtp(new File("/foo/bar.txt"));
}
@Bean
public SessionFactory<FTPFile> ftpSessionFactory() {
DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
sf.setHost("localhost");
sf.setPort(port);
sf.setUsername("foo");
sf.setPassword("foo");
sf.setTestSession(true);
return new CachingSessionFactory<FTPFile>(sf);
}
@Bean
public IntegrationFlow ftpOutboundFlow() {
return IntegrationFlow.from("toFtpChannel")
.handle(Ftp.outboundAdapter(ftpSessionFactory(), FileExistsMode.FAIL)
.useTemporaryFileName(false)
.fileNameExpression("headers['" + FileHeaders.FILENAME + "']")
.remoteDirectory(this.ftpServer.getTargetFtpDirectory().getName())
).get();
}
@MessagingGateway
public interface MyGateway {
@Gateway(requestChannel = "toFtpChannel")
void sendToFtp(File file);
}
}