|
对于最新稳定版本,请使用 Spring Integration 7.0.0! |
中小企业支持
Spring 集成支持与SMB的文件传输作。
服务器消息块(SMB)是一种简单的网络协议,允许您将文件传输到共享文件服务器。
你需要把这种依赖性纳入你的项目中:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-smb</artifactId>
<version>6.2.11</version>
</dependency>
compile "org.springframework.integration:spring-integration-smb:6.2.11"
概述
Java CIFS 客户端库被选为 CIFS/SMB 网络协议的 Java 实现。
其SmbFile抽象只需包裹到 Spring Integration 的“远程文件”基础上,比如SmbSession,SmbRemoteFileTemplate等。
SMB 通道适配器及其支持类的实现与现有的 (S)FTP 或 AWS S3 协议组件完全相似。 所以,如果你熟悉这些组件,使用起来其实挺简单的。
Spring Integration 通过提供三个客户端端端点:入站通道适配器、出站通道适配器和出站网关,支持通过 SMB 发送和接收文件。 它还提供了方便的基于命名空间的配置选项,用于定义这些客户端组件。
要使用 SMB 命名空间,请在 XML 文件的头部添加以下内容:
xmlns:int-smb="http://www.springframework.org/schema/integration/smb"
xsi:schemaLocation="http://www.springframework.org/schema/integration/smb
https://www.springframework.org/schema/integration/smb/spring-integration-smb.xsd"
SMB 会话工厂
在配置SMB适配器之前,您必须配置SMB会话工厂。 你可以用常规的 bean 定义配置 SMB 会话工厂,如下示例所示:
这SmbSessionFactory可以设置最小/最大版本的SMB协议选项。
例如,支持最小版本的 SMB 2.1 和最高版本的 SMB 3.1.1:
@Bean
public SmbSessionFactory smbSessionFactory() {
SmbSessionFactory smbSession = new SmbSessionFactory();
smbSession.setHost("myHost");
smbSession.setPort(445);
smbSession.setDomain("myDomain");
smbSession.setUsername("myUser");
smbSession.setPassword("myPassword");
smbSession.setShareAndDir("myShareAndDir");
smbSession.setSmbMinVersion(DialectVersion.SMB210);
smbSession.setSmbMaxVersion(DialectVersion.SMB311);
return smbSession;
}
这SmbSessionFactory可以用自定义初始化JCIFS。CIFSContext(国际信息系统正文).
SMB协议最小/最大版本的设置必须在你的实现中完成JCIFS。CIFSContext(国际信息系统正文). |
@Bean
public SmbSessionFactory smbSessionFactory() {
SmbSessionFactory smbSession = new SmbSessionFactory(new MyCIFSContext());
smbSession.setHost("myHost");
smbSession.setPort(445);
smbSession.setDomain("myDomain");
smbSession.setUsername("myUser");
smbSession.setPassword("myPassword");
smbSession.setShareAndDir("myShareAndDir");
return smbSession;
}
SMB 入站通道适配器
要本地下载 SMB 文件SmbInboundFileSynchronizingMessageSource提供。
它是摘要InboundFile同步消息源这需要SmbInboundFileSynchronizer注射。
对于远程文件的过滤,你仍然可以使用任何现有的文件文件列表过滤器实现,但具体情况SmbRegexPatternFileListFilter和SmbSimplePatternFileListFilter提供。
@Bean
public SmbInboundFileSynchronizer smbInboundFileSynchronizer() {
SmbInboundFileSynchronizer fileSynchronizer =
new SmbInboundFileSynchronizer(smbSessionFactory());
fileSynchronizer.setFilter(compositeFileListFilter());
fileSynchronizer.setRemoteDirectory("mySharedDirectoryPath");
fileSynchronizer.setDeleteRemoteFiles(true);
return fileSynchronizer;
}
@Bean
public CompositeFileListFilter<SmbFile> compositeFileListFilter() {
CompositeFileListFilter<SmbFile> filters = new CompositeFileListFilter<>();
filters.addFilter(new SmbRegexPatternFileListFilter("^(?i).+((\\.txt))$"));
return filters;
}
@Bean
public MessageChannel smbFileInputChannel() {
return new DirectChannel();
}
@Bean
@InboundChannelAdapter(value = "smbFileInputChannel",
poller = @Poller(fixedDelay = "2000"))
public MessageSource<File> smbMessageSource() {
SmbInboundFileSynchronizingMessageSource messageSource =
new SmbInboundFileSynchronizingMessageSource(smbInboundFileSynchronizer());
messageSource.setLocalDirectory(new File("myLocalDirectoryPath"));
messageSource.setAutoCreateLocalDirectory(true);
return messageSource;
}
对于XML配置<int-smb:入站通道适配器>组件已提供。
从6.2版本开始,你可以根据最后修改策略过滤SMB文件,使用以下方法。SmbLastModifiedFileListFilter.
该Filter可配置为年龄该属性使得过滤器只传递比该值更早的文件。
默认的年龄是60秒,但你应该选择足够大的年龄,以避免因为网络故障而提前拿到文件。
可以查看它的Java文档了解更多信息。
使用 Java DSL 配置
以下 Spring Boot 应用程序展示了如何用 Java DSL 配置入站适配器的示例:
@SpringBootApplication
public class SmbJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SmbJavaApplication.class)
.web(false)
.run(args);
}
@Bean
public SmbSessionFactory smbSessionFactory() {
SmbSessionFactory smbSession = new SmbSessionFactory();
smbSession.setHost("myHost");
smbSession.setPort(445);
smbSession.setDomain("myDomain");
smbSession.setUsername("myUser");
smbSession.setPassword("myPassword");
smbSession.setShareAndDir("myShareAndDir");
smbSession.setSmbMinVersion(DialectVersion.SMB210);
smbSession.setSmbMaxVersion(DialectVersion.SMB311);
return smbSession;
}
@Bean
public IntegrationFlow smbInboundFlow() {
return IntegrationFlow
.from(Smb.inboundAdapter(smbSessionFactory())
.preserveTimestamp(true)
.remoteDirectory("smbSource")
.regexFilter(".*\\.txt$")
.localFilename(f -> f.toUpperCase() + ".a")
.localDirectory(new File("d:\\smb_files")),
e -> e.id("smbInboundAdapter")
.autoStartup(true)
.poller(Pollers.fixedDelay(5000)))
.handle(m -> System.out.println(m.getPayload()))
.get();
}
}
SMB 流式入站通道适配器
该适配器生成带有 类型 的有效载荷的消息输入流,允许在不写入本地文件系统的情况下获取文件。
由于会话仍然开放,消费应用程序负责在文件被消耗后关闭会话。
该会话内容提供于可关闭资源头部 (IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE).
标准框架组件,例如文件分拆器和StreamTransformer,自动关闭会话。
有关这些组件的更多信息,请参见文件分流器和流变换器。
以下示例展示了如何配置入站流通道适配器:
<int-smb:inbound-streaming-channel-adapter id="smbInbound"
channel="smbChannel"
session-factory="sessionFactory"
filename-pattern="*.txt"
filename-regex=".*\.txt"
filter="filter"
filter-expression="@myFilterBean.check(#root)"
remote-file-separator="/"
comparator="comparator"
max-fetch-size="1"
remote-directory-expression="'foo/bar'">
<int:poller fixed-rate="1000" />
</int-smb:inbound-streaming-channel-adapter>
只有其中一个文件名模式,文件名正则表达式,Filter或滤波表达式是允许的。
这SmbStreamingMessageSource适配器防止远程文件的重复,满足条件SmbPersistentAcceptOnceFileListFilter基于内存SimpleMetadataStore.
默认情况下,该过滤器也会与文件名模式(或正则表达式)一起应用。
如果你需要允许重复,可以用AcceptAllFileListFilter.
其他任何用例都可以由CompositeFileListFilter(或ChainFileListFilter).
文档后面的 Java 配置展示了一种处理后移除远程文件以避免重复的技术。
欲了解更多关于SmbPersistentAcceptOnceFileListFilter,及其使用方式,请参见远程持久文件列表过滤器。
使用该最大取取大小属性用于限制每次轮询中获取的文件数量,当需要获取时。
设置为1在集群环境中运行时,使用持久过滤器。
更多信息请参见入站通道适配器:控制远程文件取用。
适配器将远程目录和文件名放入FileHeaders.REMOTE_DIRECTORY和FileHeaders.REMOTE_FILE分别是标题。
这FileHeaders.REMOTE_FILE_INFO头部提供额外的远程文件信息(默认以 JSON 表示)。
如果你设置fileInfoJson属性SmbStreamingMessageSource自false,头部包含一个SmbFileInfo对象。
使用 Java 配置配置
以下 Spring Boot 应用程序展示了如何用 Java 配置配置入站适配器的示例:
@SpringBootApplication
public class SmbJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SmbJavaApplication.class)
.web(false)
.run(args);
}
@Bean
@InboundChannelAdapter(channel = "stream")
public MessageSource<InputStream> smbMessageSource() {
SmbStreamingMessageSource messageSource = new SmbStreamingMessageSource(template());
messageSource.setRemoteDirectory("smbSource/");
messageSource.setFilter(new AcceptAllFileListFilter<>());
messageSource.setMaxFetchSize(1);
return messageSource;
}
@Bean
@Transformer(inputChannel = "stream", outputChannel = "data")
public org.springframework.integration.transformer.Transformer transformer() {
return new StreamTransformer("UTF-8");
}
@Bean
public SmbRemoteFileTemplate template() {
return new SmbRemoteFileTemplate(smbSessionFactory());
}
@ServiceActivator(inputChannel = "data", adviceChain = "after")
@Bean
public MessageHandler handle() {
return System.out::println;
}
@Bean
public ExpressionEvaluatingRequestHandlerAdvice after() {
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setOnSuccessExpression(
"@template.remove(headers['file_remoteDirectory'] + headers['file_remoteFile'])");
advice.setPropagateEvaluationFailures(true);
return advice;
}
}
注意,在这个例子中,变换器下游的消息处理程序有建议处理后会移除远程文件。
入站通道适配器:控制远程文件取用
配置入站通道适配器时,有两个属性需要考虑。每轮询最大消息数和所有轮询器一样,可以用来限制每次轮询发出的消息数量(如果有超过配置值的消息就准备好了)。最大取取大小可以限制一次从远程服务器检索的文件数量。
以下情景假设起始状态是一个空的本地目录:
-
每轮询最大消息数=2和最大取取大小=1:适配器取一个文件,发出它,再取下一个文件,再输出,然后休眠直到下一次轮询。 -
每轮询最大消息数=2和最大取取大小=2适配器取出两个文件,然后逐一输出。 -
每轮询最大消息数=2和最大取取大小=4:适配器最多可获取四个文件(如果有),并输出前两个(如果至少有两个)。 接下来的两个文件会在下一次投票中发出。 -
每轮询最大消息数=2和最大取取大小未指定:适配器获取所有远程文件并发送前两个(如果至少有两个)。 后续文件会在后续轮询中同时发布(一次两个)。 当所有文件被占用后,会再次尝试远程取用,以获取任何新的文件。
当你部署多个应用实例时,我们建议一个小型实例最大取取大小,以避免一个实例“抓取”所有文件并导致其他实例无法使用。 |
另一种用途最大取取大小如果你想停止获取远程文件,但继续处理已经被获取的文件。
设置最大取物大小属性消息源(通过编程方式,无论是使用 JMX 还是控制总线)实际上阻止适配器获取更多文件,但允许轮询器继续对已获取的文件发送消息。
如果投票器在属性变更时处于激活状态,变更将在下一次投票中生效。
同步器可以配备Comparator<SmbFile>.
这在限制通过 获取的文件数量时非常有用最大取物大小.
SMB 出站通道适配器
用于向SMB共享写入文件,以及用于XML<int-smb:出站-通道-适配器>我们使用以下组件SmbMessageHandler.
在 Java 配置 a 的情况下SmbMessageHandler应配备SmbSessionFactory(或SmbRemoteFileTemplate).
@Bean
@ServiceActivator(inputChannel = "storeToSmbShare")
public MessageHandler smbMessageHandler(SmbSessionFactory smbSessionFactory) {
SmbMessageHandler handler = new SmbMessageHandler(smbSessionFactory);
handler.setRemoteDirectoryExpression(
new LiteralExpression("remote-target-dir"));
handler.setFileNameGenerator(m ->
m.getHeaders().get(FileHeaders.FILENAME, String.class) + ".test");
handler.setAutoCreateDirectory(true);
return handler;
}
使用 Java DSL 配置
以下 Spring Boot 应用程序展示了如何使用 Java DSL 配置出站适配器的示例:
@SpringBootApplication
@IntegrationComponentScan
public class SmbJavaApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new SpringApplicationBuilder(SmbJavaApplication.class)
.web(false)
.run(args);
MyGateway gateway = context.getBean(MyGateway.class);
gateway.sendToSmb(new File("/foo/bar.txt"));
}
@Bean
public SmbSessionFactory smbSessionFactory() {
SmbSessionFactory smbSession = new SmbSessionFactory();
smbSession.setHost("myHost");
smbSession.setPort(445);
smbSession.setDomain("myDomain");
smbSession.setUsername("myUser");
smbSession.setPassword("myPassword");
smbSession.setShareAndDir("myShareAndDir");
smbSession.setSmbMinVersion(DialectVersion.SMB210);
smbSession.setSmbMaxVersion(DialectVersion.SMB311);
return smbSession;
}
@Bean
public IntegrationFlow smbOutboundFlow() {
return IntegrationFlow.from("toSmbChannel")
.handle(Smb.outboundAdapter(smbSessionFactory(), FileExistsMode.REPLACE)
.useTemporaryFileName(false)
.fileNameExpression("headers['" + FileHeaders.FILENAME + "']")
.remoteDirectory("smbTarget")
).get();
}
@MessagingGateway
public interface MyGateway {
@Gateway(requestChannel = "toSmbChannel")
void sendToSmb(File file);
}
}
中小企业出站网关
SMB出站网关提供有限的命令集,用于与远程SMB服务器交互。 支持的命令有:
-
LS(列表文件) -
NLST(国家标准)(列表文件名) -
获取(检索文件) -
MGET(检索文件) -
RM(删除文件) -
MV(移动/重命名文件) -
放(发送文件) -
mput(发送多个文件)
使用LS命令
LS列出远程文件并支持以下选项:
-
-1:检索文件名列表。 默认情况下,检索的是文件信息对象 -
-一个:包含所有文件(包括以'.'开头的文件) -
-f:不要排序列表 -
-导弹:包含目录(默认排除) -
-链接:包含符号链接(默认排除) -
-R:递归地列出远程目录
此外,文件名过滤的提供方式与入站信道适配器.
消息有效载荷由LS作是文件名的列表,或是文件信息对象(取决于你是否使用-1切换)。
这些对象提供诸如修改时间、权限等信息。
远程目录LS执行命令由file_remoteDirectory页眉。
使用递归选项时 (-R),文件名包含任何子目录元素,并表示文件相对于远程目录的相对路径。
如果你使用了-导弹选项中,每个递归目录也会作为列表中的元素返回。
在这种情况下,我们建议你不要使用-1因为你无法区分文件和目录,而在使用时可以做到这一点文件信息对象。
用NLST(国家标准)命令
NLST(国家标准)列出远程文件名,仅支持一个选项:
-
-f:不要排序列表
消息有效载荷由NLST(国家标准)作是文件名列表。
这file_remoteDirectory头部存储了NLST(国家标准)指挥部采取了行动。
使用获取命令
获取检索远程文件并支持以下选项:
-
-P保留远程文件的时间戳。 -
-流: 以流形式检索远程文件。 -
-D:成功传输后删除远程文件。 如果传输被忽略,远程文件不会被删除,因为FileExistsMode是忽视而且本地文件已经存在。
这file_remoteDirectory头部存储远程目录,且file_remoteFile头部存储文件名。
消息有效载荷由获取作是文件表示检索到的文件的对象。
如果你使用了-流选项中,有效载荷是输入流而不是文件.
对于文本文件,常见的使用场景是将此作与文件分流器或流变换器结合使用。
当以流形式消费远程文件时,你有责任关闭会期在流被消耗后。
为了方便起见,会期在可关闭资源头部,以及集成消息头访问器提供便捷的方法:
Closeable closeable = new IntegrationMessageHeaderAccessor(message).getCloseableResource();
if (closeable != null) {
closeable.close();
}
以下示例展示了如何将文件作为流消费:
<int-smb:outbound-gateway session-factory="smbSessionFactory"
request-channel="inboundGetStream"
command="get"
command-options="-stream"
expression="payload"
remote-directory="smbTarget"
reply-channel="stream" />
<int-file:splitter input-channel="stream" output-channel="lines" />
如果你在自定义组件中消费输入流,你必须关闭会期.
你可以在自定义代码里这样做,或者把消息的副本发送到服务激活器并使用SpEL,如下示例所示: |
<int:service-activator input-channel="closeSession"
expression="headers['closeableResource'].close()" />
使用MGET命令
MGET基于模式检索多个远程文件,并支持以下选项:
-
-P:保留远程文件的时间戳。 -
-R递归地检索整个目录树。 -
-x:如果没有文件匹配该模式,则抛出异常(否则返回空列表)。 -
-D:成功传输后删除每个远程文件。 如果传输被忽略,远程文件不会被删除,因为FileExistsMode是忽视而且本地文件已经存在。
消息有效载荷由MGET作是列表<文件>对象(即列表之文件每个对象表示一个检索到的文件)。
如果FileExistsMode是忽视输出消息的有效载荷不再包含因文件已存在而未被取用的文件。
此前,数组包含所有文件,包括已存在的文件。 |
你用的“确定远端路径”表达式应该得到一个以例如我的档案/获取完整的家谱树我的档案.
你可以用递归MGET,与FileExistsMode.REPLACE_IF_MODIFIED模式,用于定期在本地同步整个远程目录树。
该模式将本地文件的最后修改时间戳设置为远程文件的时间戳,无论-P(保留时间戳)选项。
|
使用递归时的注意事项(
-R)这种模式被忽视,大家默认了。
默认情况下,整个远程树都会被检索。
不过,你可以通过提供 如果你筛选一个子目录,就不会对该子目录进行额外的遍历。 这 通常,你会使用 |
持久文件列表过滤器现在具有布尔属性递归.
将该属性设置为true,也设alwaysAccept目录,这意味着对出站网关的递归作(LS和MGET)现在每次都会遍历整个目录树。
这是为了解决目录树深层变更未被检测到的问题。
另外forRecursion=真使得文件的完整路径被用作元数据存储键;这解决了当同名文件在不同目录中多次出现时,过滤器无法正常工作的问题。
重要提示:这意味着在持久的元数据存储中,无法找到顶层目录以下文件的现有密钥。
因此,该性质为false默认情况下;未来发布可能会有所变化。
你可以配置SmbSimplePatternFileListFilter和SmbRegexPatternFileListFilter通过设置alwaysAcceptDirectorties自true.
这样做可以对简单模式进行递归,如下示例所示:
<bean id="starDotTxtFilter"
class="org.springframework.integration.smb.filters.SmbSimplePatternFileListFilter">
<constructor-arg value="*.txt" />
<property name="alwaysAcceptDirectories" value="true" />
</bean>
<bean id="dotStarDotTxtFilter"
class="org.springframework.integration.smb.filters.SmbRegexPatternFileListFilter">
<constructor-arg value="^.*\.txt$" />
<property name="alwaysAcceptDirectories" value="true" />
</bean>
您可以通过以下方式提供其中一个过滤器Filter门口的财产。
使用放命令
放向远程服务器发送文件。
消息的有效载荷可以是java.io.file一个字节[],或字符串.
一个远程文件名生成器(或表达式)用于为远程文件命名。
其他可用的属性包括远程目录,临时-远程-目录以及他们的*-表达等价物:使用临时文件名和自动创建目录.
更多信息请参见模式文档。
消息有效载荷由放作是字符串该路径包含传输后服务器文件的完整路径。
使用mput命令
mput向服务器发送多个文件,并支持以下选项:
-
-R: 递归 — 发送目录和子目录中的所有文件(可能已过滤)
消息有效载荷必须是java.io.file(或字符串)表示一个本地目录。
一组文件或字符串也支持。
与放命令是支持的。
此外,你还可以用以下方法过滤本地目录中的文件mput模式,mput正则表达式,mputFilter或mput-filter-expression.
过滤器与递归一起工作,只要子目录本身通过过滤。
未通过过滤器的子目录不会被递归。
消息有效载荷由mput作是List<String>对象(即列表传输产生的远程文件路径)。
使用RM命令
这RM指挥部没有任何选项。
如果移除作成功,所得消息载荷为布林。正确.
否则,消息有效载荷为布尔值。错误.
这file_remoteDirectory头部存储远程目录,且file_remoteFile头部存储文件名。
使用MV命令
这MV指挥部没有任何选项。
这表达属性定义了“出发”路径,且重命名表达式属性定义了“去”路径。
默认情况下,重命名表达式是标题['file_renameTo'].
该表达式不得取零值或空值字符串.
如有必要,会创建所需的远程目录。
结果消息的有效载荷为布林。正确.
这file_remoteDirectory头部存储原始的远程目录,且file_remoteFile头部存储文件名。
这file_renameTo头部存储新路径。
这remoteDirectoryExpression可用于MV为了方便而命令。
如果“from”文件不是完整的文件路径,结果是remoteDirectoryExpression作为远程目录使用。
例如,如果任务只是重命名某个目录中的远程文件,“to”文件也是同样的道理。
附加指挥信息
这获取和MGET指挥支持本地文件名生成器表达式属性。
它定义了一个 SpEL 表达式,用于在传输过程中生成本地文件的名称。
评估上下文的根对象是请求消息。
这remoteFileName变量也可用。
它特别有用MGET(例如:local-filename-generator-expression=“#remoteFileName.toUpperCase() + headers.foo”).
这获取和MGET指挥支持本地目录表达式属性。
它定义了一个 SpEL 表达式,用于在传输过程中生成本地目录的名称。
评估上下文的根对象是请求消息。
这remoteDirectory变量也可用。
它对mget(例如:local-directory-expression=“'/tmp/local/' + #remoteDirectory.toUpperCase() + headers.myheader”).
该属性与本地目录属性。
对于所有命令,网关的“表达式”属性包含命令作用的路径。
对于MGET命令,表达式可能被评估为,意为检索所有文件,某目录/,以及其他以 为结尾的值。*
以下示例展示了为LS命令:
<int-smb:outbound-gateway id="gateway1"
session-factory="smbSessionFactory"
request-channel="inbound1"
command="ls"
command-options="-1"
expression="payload"
reply-channel="toSplitter"/>
发送给toSplitter频道是字符串每个对象都包含一个文件的名称。
如果你省略了command-options=“-1”,有效载荷将是文件信息对象。
你可以以空间分隔列表的形式提供选项(例如,command-options=“-1 -dirs -links”).
这获取,MGET,放和MPUT命令支持FileExistsMode性质 (模式使用命名空间支持时)。
这会影响本地文件存在时的行为(获取和MGET)或远程文件存在(放和MPUT).
支持的模式有取代,附加,失败和忽视.
为了向下兼容,默认模式为放和MPUT运算为取代.
为获取和MGET作,默认为失败.
使用 Java 配置配置
以下 Spring Boot 应用程序展示了如何用 Java 配置配置出站网关的示例:
@SpringBootApplication
public class SmbJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SmbJavaApplication.class)
.web(false)
.run(args);
}
@Bean
public SmbSessionFactory smbSessionFactory() {
SmbSessionFactory smbSession = new SmbSessionFactory();
smbSession.setHost("myHost");
smbSession.setPort(445);
smbSession.setDomain("myDomain");
smbSession.setUsername("myUser");
smbSession.setPassword("myPassword");
smbSession.setShareAndDir("myShareAndDir");
smbSession.setSmbMinVersion(DialectVersion.SMB210);
smbSession.setSmbMaxVersion(DialectVersion.SMB311);
return smbSession;
}
@Bean
@ServiceActivator(inputChannel = "smbChannel")
public MessageHandler handler() {
SmbOutboundGateway smbOutboundGateway =
new SmbOutboundGateway(smbSessionFactory(), "'my_remote_dir/'");
smbOutboundGateway.setOutputChannelName("replyChannel");
return smbOutboundGateway;
}
}
使用 Java DSL 配置
以下 Spring Boot 应用程序展示了如何用 Java DSL 配置出站网关的示例:
@SpringBootApplication
public class SmbJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SmbJavaApplication.class)
.web(false)
.run(args);
}
@Bean
public SmbSessionFactory smbSessionFactory() {
SmbSessionFactory smbSession = new SmbSessionFactory();
smbSession.setHost("myHost");
smbSession.setPort(445);
smbSession.setDomain("myDomain");
smbSession.setUsername("myUser");
smbSession.setPassword("myPassword");
smbSession.setShareAndDir("myShareAndDir");
smbSession.setSmbMinVersion(DialectVersion.SMB210);
smbSession.setSmbMaxVersion(DialectVersion.SMB311);
return smbSession;
}
@Bean
public SmbOutboundGatewaySpec smbOutboundGateway() {
return Smb.outboundGateway(smbSessionFactory(),
AbstractRemoteFileOutboundGateway.Command.MGET, "payload")
.options(AbstractRemoteFileOutboundGateway.Option.RECURSIVE)
.regexFileNameFilter("(subSmbSource|.*.txt)")
.localDirectoryExpression("'localDirectory/' + #remoteDirectory")
.localFilenameExpression("#remoteFileName.replaceFirst('smbSource', 'localTarget')");
}
@Bean
public IntegrationFlow smbFlow(AbstractRemoteFileOutboundGateway<SmbFile> smbOutboundGateway) {
return f -> f
.handle(smbOutboundGateway)
.channel(c -> c.queue("remoteFileOutputChannel"));
}
}
出站网关部分成功(MGET和mput)
在对多个文件执行作时(通过MGET和mput例外可能发生在一个或多个文件传输后一段时间。
在这种情况下,a部分成功例外被抛出。
还有常见的消息异常性质(失败消息和原因),该例外还有两个额外性质:
-
部分结果:转会成功的结果。 -
衍生输入: 由请求消息生成的文件列表(例如本地文件,用于传输mput).
这些属性可以帮助你判断哪些文件被成功传输,哪些没有。
递归情况下mput这部分成功例外可能已经筑巢部分成功例外实例。
考虑以下目录结构:
root/
|- file1.txt
|- subdir/
| - file2.txt
| - file3.txt
|- zoo.txt
如果异常发生在file3.txt这部分成功例外被门扔出去衍生输入之file1.txt,副导演和zoo.txt和部分结果之file1.txt.
其原因是另一个部分成功例外跟衍生输入之file2.txt和file3.txt和部分结果之file2.txt.
远程文件信息
这SmbStreamingMessageSource (SMB 流式入站通道适配器),SmbInboundFileSynchronizingMessageSource (SMB 入站通道适配器)以及“read”命令SmbOutboundGateway (中小企业出站网关)在消息中提供额外的头部,以便产生关于远程文件的信息:
-
FileHeaders.REMOTE_HOST_PORT- 在文件传输作中,远程会话连接的host:port对; -
FileHeaders.REMOTE_DIRECTORY-作已执行的远程目录; -
FileHeaders.REMOTE_FILE- 远程文件名;仅适用于单文件作。
自从......SmbInboundFileSynchronizingMessageSource不会对远程文件产生消息,但通过本地副本,摘要InboundFileSynchronizer存储关于远程文件的信息元数据存储(可在外部配置)采用URI风格(protocol://host:port/remoteDirectory#remoteFileName)在同步作中。
这些元数据由SmbInboundFileSynchronizingMessageSource当轮询本地文件时。
当本地文件被删除时,建议删除其元数据条目。
这摘要InboundFileSynchronizer提供removeRemoteFileMetadata()为此目的回归。
此外,还有一个setMetadataStorePrefix()用于元数据密钥。
建议该前缀与元数据存储-基于文件列表过滤器实现方式相同元数据存储实例在这些组件之间共享,以避免因过滤器和摘要InboundFileSynchronizer元数据输入键使用相同的本地文件名。