Spring集成文件读取 [英] Spring Integration File reading
问题描述
我是 Spring Integration 的新手.我正在研究解决方案,但在使用入站文件适配器 ( FileReadingMessageSource ) 时遇到了特定问题.我必须从不同目录读取文件并处理它们并将文件保存在不同目录中.据我了解,目录名称在流程开始时是固定的.有人可以帮助我更改不同请求的目录名称吗.
I am newbie to Spring Integration. I am working on solution, but I am stuck on a specific issue while using inbound file adapter ( FileReadingMessageSource ). I have to read files from different directories and process them and save the files in different directories. As I understand, the directory name is fixed at the start of the flow. Can some one help me on changing the directory name for different requests.
我尝试了以下操作.首先,我不确定这是否是正确的方法,尽管它只适用于一个目录.我认为 Poller 正在等待更多文件并且再也没有回来读取另一个目录.
I attempted the following. First of all, I am not sure whether it is correct way to about and although it worked for only one directory. I think Poller was waiting for more files and never came back to read another directory.
@SpringBootApplication
@EnableIntegration
@IntegrationComponentScan
public class SiSampleFileProcessor {
@Autowired
MyFileProcessor myFileProcessor;
@Value("${si.outdir}")
String outDir;
@Autowired
Environment env;
public static void main(String[] args) throws IOException {
ConfigurableApplicationContext ctx = new SpringApplication(SiSampleFileProcessor.class).run(args);
FileProcessingService gateway = ctx.getBean(FileProcessingService.class);
boolean process = true;
while (process) {
System.out.println("Please enter the input Directory: ");
String inDir = new Scanner(System.in).nextLine();
if ( inDir.isEmpty() || inDir.equals("exit") ) {
process=false;
} else {
System.out.println("Processing... " + inDir);
gateway.processFilesin(inDir);
}
}
ctx.close();
}
@MessagingGateway(defaultRequestChannel="requestChannel")
public interface FileProcessingService {
String processFilesin( String inputDir );
}
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
return Pollers.fixedDelay(1000).get();
}
@Bean
public MessageChannel requestChannel() {
return new DirectChannel();
}
@ServiceActivator(inputChannel = "requestChannel")
@Bean
GenericHandler<String> fileReader() {
return new GenericHandler<String>() {
@Override
public Object handle(String p, Map<String, Object> map) {
FileReadingMessageSource fileSource = new FileReadingMessageSource();
fileSource.setDirectory(new File(p));
Message<File> msg;
while( (msg = fileSource.receive()) != null ) {
fileInChannel().send(msg);
}
return null; // Not sure what to return!
}
};
}
@Bean
public MessageChannel fileInChannel() {
return MessageChannels.queue("fileIn").get();
}
@Bean
public IntegrationFlow fileProcessingFlow() {
return IntegrationFlows.from(fileInChannel())
.handle(myFileProcessor)
.handle(Files.outboundAdapter(new File(outDir)).autoCreateDirectory(true).get())
.get();
}
}
根据 Gary 的回复,将一些方法替换为
Based on Gary's response replaced some methods as
@MessagingGateway(defaultRequestChannel="requestChannel")
public interface FileProcessingService {
boolean processFilesin( String inputDir );
}
@ServiceActivator(inputChannel = "requestChannel")
public boolean fileReader(String inDir) {
FileReadingMessageSource fileSource = new FileReadingMessageSource();
fileSource.setDirectory(new File(inDir));
fileSource.afterPropertiesSet();
fileSource.start();
Message<File> msg;
while ((msg = fileSource.receive()) != null) {
fileInChannel().send(msg);
}
fileSource.stop();
System.out.println("Sent all files in directory: " + inDir);
return true;
}
现在它按预期工作.
推荐答案
FileReadingMessageSource
在内部使用了一个 DirectoryScanner
;它通常在注入属性后由 Spring 设置.由于您在 Spring 之外管理对象,因此需要调用 Spring bean 初始化和生命周期方法 afterPropertiesSet()
、 start()
和 stop()代码>.
The FileReadingMessageSource
uses a DirectoryScanner
internally; it is normally set up by Spring after the properties are injected. Since you are managing the object outside of Spring, you need to call Spring bean initialization and lifecycle methods afterPropertiesSet()
, start()
and stop()
.
当接收返回 null 时调用 stop()
.
Call stop()
when the receive returns null.
> return null; // Not sure what to return!
如果你什么都不返回,你的调用线程将挂在网关中等待响应.您可以更改网关以返回 void
或者,由于您的网关需要一个字符串,因此只需返回一些值.
If you return nothing, your calling thread will hang in the gateway waiting for a response. You could change the gateway to return void
or, since your gateway is expecting a String, just return some value.
但是,您的调用代码无论如何都不会查看结果.
However, your calling code is not looking at the result anyway.
> gateway.processFilesin(inDir);
另外,从@ServiceActivator
中删除@Bean
;使用这种风格,bean 类型必须是 MessageHandler
.
Also, remove the @Bean
from the @ServiceActivator
; with that style, the bean type must be MessageHandler
.
这篇关于Spring集成文件读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!