我使用spring集成来轮询文件。此单个文件包含多个报告。我想将文件拆分为报告文件并保存为不同的文件。
<int-file:inbound-channel-adapter id="filesIn"
directory="file:${fileInDirectory}"
filename-pattern="*.txt"
prevent-duplicates="true">
<int:poller id="poller" fixed-delay="5000"/>
</int-file:inbound-channel-adapter>
<int:service-activator input-channel="filesIn"
output-channel="filesOut"
ref="handler"/>
<int-file:outbound-channel-adapter id="filesOut"
directory="file:${archiveDirectory}"
delete-source-files="true"/>
在处理程序内部,处理程序内部的处理方法如下所示。
public List<ReportContent> splitTextToReports(File file){
// split the file
// store the file content text to ReportContent object
// add to a List of ReportContent
}
ReportContent 包含以下字段
reportData(将保存在新文件中的文本)
REPORTTYPE
reportDate
每个ReportContent都需要另一个处理。
以下是处理上述方法返回的列表的每个元素的方法。
public void processReportContent (ReportContent reportContent){
// process report content and save the file in the relevant place
}
问题的两个部分。
答案 0 :(得分:2)
1。
而不是<int:service-activator input-channel="filesIn"...
我会添加一个链
<int:chain id="processor" input-channel="filesIn" output-channel="filesOut">
<int:splitter>
<bean class="...your impl of org.springframework.integration.splitter.AbstractMessageSplitter..."/>
</int:splitter>
</int:chain>
并将您的splitTextToReports
逻辑移动到此拆分器中。因此,在拆分器之后的链中,您将拥有ReportContent
个实例的平坦流。
2。
在拆分器之后在链中添加转换步骤。将processReportContent
逻辑放在这里。转换结果:您的报告在有效负载中的字符串,以及&#39;文件名中的文件名&#39;消息头变量。
您的变压器的API可能是这样的
interface ReportContentTransformer {
Message<?> transform(ReportContent content);
}
链条看起来像
<int:chain id="processor" input-channel="filesIn" output-channel="filesOut">
<int:splitter>
...
</int:splitter>
<int:transformer ref="...ref on your ReportContentTransformer interface implementation bean..." method="transform"/>
</int:chain>
3。
添加到您的outbound-channel-adapter
属性
filename-generator-expression="headers.get('filename')"
在文件存储时使用filename
变量中的文件名。
答案 1 :(得分:1)
要并行处理项目,<splitter>
总是有一个技巧,比如下游ExecutorChannel
,所以在分割项目的迭代过程中,我们会在发送前一个项目后立即移动到下一个项目。“ p>
此外,为了获得更好的吞吐量,splitter
支持Iterator
进行流式传输。
我打算为你的任务建议FileSplitter
,但我想你不是按行划分,而是由其他识别器划分。也许你的内容只是XML或JSON,它可以很容易地确定部分内容。
从这里开始,为您的案例提供一些Iterator
实施可能并不那么容易。
但我觉得没关系。您已经具有拆分逻辑并构建了List<ReportContent>
。
关于ConcurrentMap
。
当下一次调用同一个密钥只返回缓存中的值时,如何查看{“1}} Spring对”硬“服务的支持?
为此,您可以使用@Cacheable
上的directory-expression
:
<int-file:outbound-channel-adapter>
您也可以接受与文件名相同的技术。
注意:请注意文件名的默认标头:<int-file:outbound-channel-adapter directory-expression="@reportPathService.getPath(payload)" />
。