このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Integration 6.4.3 を使用してください! |
FTP 送信ゲートウェイ
FTP 送信ゲートウェイは、リモート FTP または FTPS サーバーと対話するための限られたコマンドセットを提供します。サポートされているコマンドは次のとおりです。
ls
(リストファイル)nlst
(リストファイル名)get
(ファイルを取得する)mget
(ファイルの取得)rm
(ファイルを削除)mv
(ファイルの移動 / 名前変更)put
(ファイルの送信)mput
(複数のファイルを送信する)
ls
コマンドの使用
ls
はリモートファイルをリストし、次のオプションをサポートします。
-1
: ファイル名のリストを取得します。デフォルトでは、FileInfo
オブジェクトのリストを取得します。-a
: すべてのファイルを含める ( "." で始まるものを含む)-f
: リストをソートしないでください-dirs
: インクルードディレクトリ (それらはデフォルトで除外されます)-links
: シンボリックリンクを含める (それらはデフォルトで除外されます)-R
: リモートディレクトリを再帰的にリストする
さらに、inbound-channel-adapter
と同じ方法で、ファイル名のフィルタリングが提供されます。FTP 受信チャネルアダプターを参照してください。
ls
操作の結果のメッセージペイロードは、ファイル名のリストまたは FileInfo
オブジェクトのリストです。これらのオブジェクトは、変更された時間、権限、その他の詳細などの情報を提供します。
ls
コマンドが実行されたリモートディレクトリは、file_remoteDirectory
ヘッダーで提供されます。
再帰オプション(-R
)を使用する場合、fileName
にはサブディレクトリ要素が含まれ、ファイルへの相対パス(リモートディレクトリに対する相対パス)を表します。-dirs
オプションが含まれている場合、各再帰ディレクトリもリスト内の要素として返されます。この場合、-1
オプションを使用しないことをお勧めします。FileInfo
オブジェクトで実行できるディレクトリとファイルを区別できないためです。
バージョン 4.3 以降、FtpSession
は list()
および listNames()
メソッドの null
をサポートします。expression
属性は省略できます。便宜上、Java 構成には、expression
引数を持たない 2 つのコンストラクターがあります。または LS
、NLST
、PUT
、MPUT
コマンドの場合、null
は、FTP プロトコルに従ってクライアントの作業ディレクトリとして扱われます。リクエストメッセージに対してリモートパスを評価するには、他のすべてのコマンドを expression
とともに提供する必要があります。DefaultFtpSessionFactory
を継承し、postProcessClientAfterConnect()
コールバックを実装するときに、FTPClient.changeWorkingDirectory()
関数を使用して作業ディレクトリを設定できます。
nlst
コマンドの使用
バージョン 5 では、nlst
コマンドのサポートが導入されました。
nlst
はリモートファイル名をリストし、1 つのオプションのみをサポートします。
-f
: リストをソートしないでください
nlst
操作から生じるメッセージペイロードは、ファイル名のリストです。
nlst
コマンドが実行されたリモートディレクトリは、file_remoteDirectory
ヘッダーで提供されます。
LIST
コマンドを使用する ls
コマンドの -1
オプションとは異なり、nlst
コマンドは、ターゲット FTP サーバーに NLST
コマンドを送信します。このコマンドは、サーバーが LIST
をサポートしていない場合に役立ちます(たとえば、セキュリティ制限のため)。nlst
操作の結果は、他の詳細なしの名前です。フレームワークは、エンティティがディレクトリであるかどうかを判断できません。たとえば、フィルタリングや再帰的なリストを実行できます。
get
コマンドの使用
get
はリモートファイルを取得します。次のオプションをサポートしています。
-P
: リモートファイルのタイムスタンプを保持します。-stream
: リモートファイルをストリームとして取得します。-D
: 転送に成功したら、リモートファイルを削除します。FileExistsMode
はIGNORE
であり、ローカルファイルがすでに存在するため、転送が無視される場合、リモートファイルは削除されません。
file_remoteDirectory
ヘッダーはリモートディレクトリ名を提供し、file_remoteFile
ヘッダーはファイル名を提供します。
get
操作の結果として生成されるメッセージペイロードは、取得されたファイルを表す File
オブジェクト、または -stream
オプションを使用する場合は InputStream
です。-stream
オプションを使用すると、ファイルをストリームとして取得できます。テキストファイルの場合、一般的な使用例は、この操作をファイルスプリッターまたはストリームトランスフォーマーと組み合わせることです。リモートファイルをストリームとして使用する場合、ストリームの使用後に Session
を閉じる必要があります。便宜上、Session
は closeableResource
ヘッダーで提供されており、IntegrationMessageHeaderAccessor
のコンビニエンスメソッドを使用してアクセスできます。次の例は、コンビニエンスメソッドの使用メソッドを示しています。
Closeable closeable = new IntegrationMessageHeaderAccessor(message).getCloseableResource();
if (closeable != null) {
closeable.close();
}
ファイルスプリッターやストリームトランスフォーマーなどのフレームワークコンポーネントは、データが転送された後、セッションを自動的に閉じます。
次の例は、ファイルをストリームとして使用する方法を示しています。
<int-ftp:outbound-gateway session-factory="ftpSessionFactory"
request-channel="inboundGetStream"
command="get"
command-options="-stream"
expression="payload"
remote-directory="ftpTarget"
reply-channel="stream" />
<int-file:splitter input-channel="stream" output-channel="lines" />
カスタムコンポーネントで入力ストリームを使用する場合は、Session を閉じる必要があります。次の例に示すように、カスタムコードで、またはメッセージのコピーを service-activator にルーティングして SpEL を使用することで、これを行うことができます。 |
<int:service-activator input-channel="closeSession"
expression="headers['closeableResource'].close()" />
mget
コマンドの使用
mget
は、パターンに基づいて複数のリモートファイルを取得し、次のオプションをサポートします。
-P
: リモートファイルのタイムスタンプを保持します。-R
: ディレクトリツリー全体を再帰的に取得します。-x
: パターンに一致するファイルがない場合は例外をスローします(そうでない場合は空のリストが返されます)。-D
: 転送が成功したら、各リモートファイルを削除します。FileExistsMode
はIGNORE
であり、ローカルファイルがすでに存在するため、転送が無視される場合、リモートファイルは削除されません。
mget
操作の結果のメッセージペイロードは、List<File>
オブジェクト(つまり、File
オブジェクトの List
、それぞれが取得したファイルを表す)です。
バージョン 5.0 以降、FileExistsMode が IGNORE の場合、出力メッセージのペイロードには、ファイルがすでに存在するためにフェッチされなかったファイルが含まれなくなりました。以前は、リストには既存のファイルを含むすべてのファイルが含まれていました。 |
リモートパスを決定するために使用される式は、 で終わる結果を生成する必要があります。
somedir/
は、somedir
の完全なツリーをフェッチします。
バージョン 5.0 以降、再帰的な mget
を新しい FileExistsMode.REPLACE_IF_MODIFIED
モードと組み合わせて、リモートディレクトリツリー全体を定期的にローカルに同期することができます。このモードは、-P
(タイムスタンプを保持)オプションに関係なく、ローカルファイルの最終変更タイムスタンプをリモートタイムスタンプに置き換えます。
再帰を使用する ( -R ) パターンは無視され、 サブディレクトリがフィルタリングされると、そのサブディレクトリの追加の走査は実行されません。
通常、リモートディレクトリ構造がローカルに保持されるように、 |
永続ファイルリストフィルターにブールプロパティ forRecursion
が追加されました。このプロパティを true
に設定すると、alwaysAcceptDirectories
も設定されます。これは、送信ゲートウェイ(ls
および mget
)での再帰操作が常にディレクトリツリー全体を毎回トラバースすることを意味します。これは、ディレクトリツリーの奥深くで変更が検出されなかった問題を解決するためです。さらに、forRecursion=true
により、ファイルへのフルパスがメタデータストアキーとして使用されます。これにより、同じ名前のファイルが異なるディレクトリに複数回表示された場合にフィルターが正しく機能しなかった問題が解決されます。重要: これは、永続メタデータストア内の既存のキーが、最上位ディレクトリにあるファイルで見つからないことを意味します。このため、プロパティはデフォルトで false
です。これは将来のリリースで変更される可能性があります。
バージョン 5.0 から、FtpSimplePatternFileListFilter
および FtpRegexPatternFileListFilter
は、alwaysAcceptDirectories
プロパティを true
に設定することにより、常にディレクトリを渡すように構成できます。これにより、次の例に示すように、単純なパターンの再帰が可能になります。
<bean id="starDotTxtFilter"
class="org.springframework.integration.ftp.filters.FtpSimplePatternFileListFilter">
<constructor-arg value="*.txt" />
<property name="alwaysAcceptDirectories" value="true" />
</bean>
<bean id="dotStarDotTxtFilter"
class="org.springframework.integration.ftp.filters.FtpRegexPatternFileListFilter">
<constructor-arg value="^.*\.txt$" />
<property name="alwaysAcceptDirectories" value="true" />
</bean>
前の例のようなフィルターを定義したら、ゲートウェイで filter
プロパティを設定することにより、フィルターを使用できます。
送信ゲートウェイの部分的な成功 (mget
および mput
) も参照してください。
put
コマンドの使用
put
コマンドは、ファイルを リモートサーバーに送信します。メッセージのペイロードは、java.io.File
、byte[]
、または String
です。remote-filename-generator
(または式) を使用して、リモートファイルに名前を付けます。その他の使用可能な属性には、remote-directory
、temporary-remote-directory
、それらに相当する *-expression
である use-temporary-file-name
および auto-create-directory
が含まれます。詳細については、スキーマ [GitHub] (英語) のドキュメントを参照してください。
put
操作の結果として生じるメッセージペイロードは、転送後のサーバー上のファイルの完全パスを表す String
です。
バージョン 5.2 では chmod
属性が導入され、アップロード後にリモートファイルのアクセス許可が変更されます。従来の Unix 8 進形式を使用できます(たとえば、600
では、ファイル所有者に対してのみ読み取り / 書き込みが許可されます)。java を使用してアダプターを構成する場合、setChmod(0600)
を使用できます。FTP サーバーが SITE CHMOD
サブコマンドをサポートしている場合にのみ適用されます。
mput
コマンドの使用
mput
は複数のファイルをサーバーに送信し、1 つのオプションのみをサポートします。
-R
: 再帰的。ディレクトリとそのサブディレクトリ内のすべてのファイル(おそらくフィルタリングされた)を送信します。
メッセージペイロードは、ローカルディレクトリを表す java.io.File
(または String
)でなければなりません。バージョン 5.1 以降、File
または String
のコレクションもサポートされています。
このコマンドは、put
コマンドと同じ属性をサポートしています。さらに、ローカルディレクトリ内のファイルは、mput-pattern
、mput-regex
、mput-filter
または mput-filter-expression
のいずれかでフィルターできます。サブディレクトリ自体がフィルターを通過する限り、フィルターは再帰で機能します。フィルターを通過しないサブディレクトリは再帰されません。
mput
操作の結果のメッセージペイロードは、List<String>
オブジェクト(つまり、転送の結果としてのリモートファイルパスの List
)です。
送信ゲートウェイの部分的な成功 (mget
および mput
) も参照してください。
バージョン 5.2 では、chmod
属性が導入されました。これにより、アップロード後にリモートファイルの権限を変更できます。従来の Unix 8 進形式を使用できます(たとえば、600
では、ファイル所有者に対してのみ読み取り / 書き込みが許可されます)。Java を使用してアダプターを構成する場合、setChmodOctal("600")
または setChmod(0600)
を使用できます。FTP サーバーが SITE CHMOD
サブコマンドをサポートしている場合にのみ適用されます。
rm
コマンドの使用
rm
コマンドはファイルを削除します。
rm
コマンドにはオプションがありません。
rm
操作の結果としてのメッセージペイロードは、削除が成功した場合は Boolean.TRUE
、そうでない場合は Boolean.FALSE
です。file_remoteDirectory
ヘッダーはリモートディレクトリを提供し、file_remoteFile
ヘッダーはファイル名を提供します。
mv
コマンドの使用
mv
コマンドはファイルを移動します。
mv
コマンドにはオプションがありません。
expression
属性は "from" パスを定義し、rename-expression
属性は "to" パスを定義します。デフォルトでは、rename-expression
は headers['file_renameTo']
です。この式は null または空の String
に評価してはなりません。必要に応じて、必要なリモートディレクトリが作成されます。結果メッセージのペイロードは Boolean.TRUE
です。file_remoteDirectory
ヘッダーは元のリモートディレクトリを提供し、file_remoteFile
ヘッダーはファイル名を提供します。新しいパスは file_renameTo
ヘッダーにあります。
バージョン 5.5.6 以降、remoteDirectoryExpression
を mv
コマンドで使用できるようになりました。"from" ファイルが完全なファイルパスでない場合、remoteDirectoryExpression
の結果がリモートディレクトリとして使用されます。同じことが "to" ファイルにも当てはまります。たとえば、タスクがディレクトリ内のリモートファイルの名前を変更するだけの場合です。
FTP 送信ゲートウェイコマンドに関する追加情報
get
および mget
コマンドは、local-filename-generator-expression
属性をサポートしています。転送中にローカルファイルの名前を生成する SpEL 式を定義します。評価コンテキストのルートオブジェクトはリクエストメッセージです。mget
で特に有用な remoteFileName
変数も使用可能です(例: local-filename-generator-expression="#remoteFileName.toUpperCase() + headers.something"
)。
get
および mget
コマンドは、local-directory-expression
属性をサポートしています。転送中にローカルディレクトリの名前を生成する SpEL 式を定義します。評価コンテキストのルートオブジェクトはリクエストメッセージですが、mget
で特に有用な remoteDirectory
変数も使用可能です(例: local-directory-expression="'/tmp/local/' + #remoteDirectory.toUpperCase() + headers.something"
)。この属性は、local-directory
属性と相互に排他的です。
すべてのコマンドについて、ゲートウェイの「式」プロパティは、コマンドが機能するパスを提供します。mget
コマンドの場合、式は "'、すべてのファイルを取得することを意味する、または ' somedirectory/" などと評価される場合があります。
次の例は、ls
コマンド用に構成されたゲートウェイを示しています。
<int-ftp:outbound-gateway id="gateway1"
session-factory="ftpSessionFactory"
request-channel="inbound1"
command="ls"
command-options="-1"
expression="payload"
reply-channel="toSplitter"/>
toSplitter
チャネルに送信されるメッセージのペイロードは、それぞれファイルの名前を含む String
オブジェクトのリストです。command-options
属性が省略された場合、FileInfo
オブジェクトを保持します。スペースで区切られたオプション(たとえば、command-options="-1 -dirs -links"
)を使用します。
バージョン 4.2 以降、GET
、MGET
、PUT
、MPUT
コマンドは FileExistsMode
プロパティ(名前空間サポートを使用する場合は mode
)をサポートします。これは、ローカルファイルが存在する場合(GET
および MGET
)またはリモートファイルが存在する場合(PUT
および MPUT
)の動作に影響します。サポートされているモードは REPLACE
、APPEND
、FAIL
、IGNORE
です。下位互換性のために、PUT
および MPUT
操作のデフォルトモードは REPLACE
です。GET
および MGET
操作の場合、デフォルトは FAIL
です。
バージョン 5.0 から、setWorkingDirExpression()
(XML の working-dir-expression
)オプションが FtpOutboundGateway
(XML の <int-ftp:outbound-gateway>
)で提供されます。実行時にクライアントの作業ディレクトリを変更できます。式はリクエストメッセージに対して評価されます。前の作業ディレクトリは、各ゲートウェイ操作の後に復元されます。
Java 構成を使用した構成
次の Spring Boot アプリケーションは、Java 構成で送信ゲートウェイを構成する方法の例を示しています。
@SpringBootApplication
public class FtpJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(FtpJavaApplication.class)
.web(false)
.run(args);
}
@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() {
FtpOutboundGateway ftpOutboundGateway =
new FtpOutboundGateway(ftpSessionFactory(), "ls", "'my_remote_dir/'");
ftpOutboundGateway.setOutputChannelName("lsReplyChannel");
return ftpOutboundGateway;
}
}
Java DSL を使用した構成
次の Spring Boot アプリケーションは、送信ゲートウェイを Java DSL で構成する方法の例を示しています。
@SpringBootApplication
public class FtpJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(FtpJavaApplication.class)
.web(false)
.run(args);
}
@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 FtpOutboundGatewaySpec ftpOutboundGateway() {
return Ftp.outboundGateway(ftpSessionFactory(),
AbstractRemoteFileOutboundGateway.Command.MGET, "payload")
.options(AbstractRemoteFileOutboundGateway.Option.RECURSIVE)
.regexFileNameFilter("(subFtpSource|.*1.txt)")
.localDirectoryExpression("'localDirectory/' + #remoteDirectory")
.localFilenameExpression("#remoteFileName.replaceFirst('ftpSource', 'localTarget')");
}
@Bean
public IntegrationFlow ftpMGetFlow(AbstractRemoteFileOutboundGateway<FTPFile> ftpOutboundGateway) {
return f -> f
.handle(ftpOutboundGateway)
.channel(c -> c.queue("remoteFileOutputChannel"));
}
}
送信ゲートウェイの部分的な成功 (mget
および mput
)
(mget
および mput
を使用して)複数のファイルに対して操作を実行すると、1 つ以上のファイルが転送された後、しばらく時間が経過する場合があります。この場合(バージョン 4.2 以降)、PartialSuccessException
がスローされます。通常の MessagingException
プロパティ(failedMessage
および cause
)と同様に、この例外には 2 つの追加プロパティがあります。
partialResults
: 正常な転送結果。derivedInput
: リクエストメッセージから生成されたファイルのリスト(たとえば、mput
用に転送するローカルファイル)。
これらの属性により、正常に転送されたファイルと転送されなかったファイルを判別できます。
再帰的な mput
の場合、PartialSuccessException
にはネストされた PartialSuccessException
出現箇所があります。
次のディレクトリ構造を考慮してください。
root/
|- file1.txt
|- subdir/
| - file2.txt
| - file3.txt
|- zoo.txt
file3.txt
で例外が発生した場合、ゲートウェイによってスローされた PartialSuccessException
には、file1.txt
、subdir
、zoo.txt
の derivedInput
と file1.txt
の partialResults
があります。その cause
は、file2.txt
の derivedInput
と file2.txt
の file3.txt
および partialResults
を備えた別の PartialSuccessException
です。