1引言
文件支持是Spring Integration与外部系统通信的另一个端点。 在这种情况下,它提供了几个组件来读取,写入和转换文件。 在这篇文章中,我们将编写一个监视目录的应用程序,以便读取其中的所有文件。 具体而言,它执行以下操作:
- 当应用程序启动时,它将读取目录中存在的所有文件。
- 然后,应用程序将密切注意目录以检测新文件和已修改的现有文件。
可以在Github中找到源代码。
2配置
该应用程序是使用Spring Boot构建的,因为它大大简化了配置。 要创建应用程序的初始基础结构,您可以转到https://start.spring.io/ ,选择Integration模块并生成项目。 然后,您可以在自己喜欢的IDE中打开zip文件。
我在pom.xml中添加了一些依赖项,例如commons.io或Spring Integration Java DSL。 我的pom.xml文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xpadro.spring.integration</groupId>
<artifactId>file-read-directory</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>file-read-directory</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Integration - Java DSL -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-java-dsl</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
起点是FileReadDirectoryApplication:
@SpringBootApplication
public class FileReadDirectoryApplication {
public static void main(String[] args) throws IOException, InterruptedException {
SpringApplication.run(FileReadDirectoryApplication.class, args);
}
}
从这里开始,我们将添加Spring Integration组件以从文件系统的特定文件夹中读取。
3添加适配器
为了从文件系统读取,我们需要一个入站通道适配器。 适配器是一个文件读取消息源,它负责轮询文件系统目录中的文件,并从找到的每个文件中创建一条消息。
@Bean
@InboundChannelAdapter(value = "fileInputChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
CompositeFileListFilter<File> filters = new CompositeFileListFilter<>();
filters.addFilter(new SimplePatternFileListFilter("*.txt"));
filters.addFilter(new LastModifiedFileFilter());
FileReadingMessageSource source = new FileReadingMessageSource();
source.setAutoCreateDirectory(true);
source.setDirectory(new File(DIRECTORY));
source.setFilter(filters);
return source;
}
我们可以通过为消息源设置过滤器列表来防止某些类型的文件被轮询。 对于此示例,已包含两个过滤器:
- SimplePatternFileListFilter :Spring提供的过滤器。 仅具有指定扩展名的文件将被轮询。 在这种情况下,将仅接受文本文件。
- LastModifiedFileFilter :自定义过滤器。 该过滤器跟踪已轮询的文件,并将过滤自上次跟踪以来未修改的文件。
4处理文件
对于每个轮询的文件,我们将其内容转换为String,然后再将其传递给处理器。 为此,Spring已经提供了一个组件:
@Bean
public FileToStringTransformer fileToStringTransformer() {
return new FileToStringTransformer();
}
因此,处理器将收到Message <String>,而不是接收Message <File>。 文件处理器是我们的自定义组件,它将执行与打印文件内容一样高级的操作:
public class FileProcessor {
private static final String HEADER_FILE_NAME = "file_name";
private static final String MSG = "%s received. Content: %s";
public void process(Message<String> msg) {
String fileName = (String) msg.getHeaders().get(HEADER_FILE_NAME);
String content = msg.getPayload();
System.out.println(String.format(MSG, fileName, content));
}
}
5建立流程
现在我们已经准备好所有必需的组件,让我们构建流程。 我们正在使用Spring Integration Java DSL,因为它使流程更具可读性:
@Bean
public IntegrationFlow processFileFlow() {
return IntegrationFlows
.from("fileInputChannel")
.transform(fileToStringTransformer())
.handle("fileProcessor", "process").get();
}
@Bean
public MessageChannel fileInputChannel() {
return new DirectChannel();
}
6运行应用程序
在我的目录中,我已经有一个名为“ previousFile.txt”的文件。 启动应用程序后,我们将创建两个文件并修改其中一个。
public static void main(String[] args) throws IOException, InterruptedException {
SpringApplication.run(FileReadDirectoryApplication.class, args);
createFiles();
}
private static void createFiles() throws IOException, InterruptedException {
createFile("file1.txt", "content");
createFile("file2.txt", "another file");
appendFile("file1.txt", " modified");
}
如果运行该应用程序,则应该看到以下打印语句:
previousFile.txt received. Content: previous content
file1.txt received. Content: content
file2.txt received. Content: another file
file1.txt received. Content: content modified
7结论
这个例子展示了使用Spring Integration从目录中读取文件非常简单,显然是借助Spring Boot来简化配置。 根据您的需要,您可以将自己的自定义过滤器添加到消息源,或者使用Spring提供的另一个过滤器,例如RegexPatternFileListFilter 。 您可以在此处检查其他实现。
如果您发现此帖子有用,请分享或给我的存储库加注星标:
我正在Google Plus和Twitter上发布我的新帖子。 如果您要更新新内容,请关注我。
翻译自: https://www.javacodegeeks.com/2016/07/spring-integration-polling-file-creation-modification.html