java - Spring Integration 抛出 NoSuchFileException

标签 java spring spring-boot spring-integration

我尝试构建一个简单的 Spring Integration 文件夹用于数据导入。但在处理最后一个文件时,进程会抛出 NoSuchFileException 。 我正在使用 Spring 5.0.5(在本演示中使用 Spring Boot 2.0.1)

配置:

<bean id="dataImporter" class="com.example.demo.DataImporter" />

<bean id="XMLFileListFilter" class="org.springframework.integration.file.filters.SimplePatternFileListFilter" >
    <constructor-arg value="*.xml" />
</bean>

<bean id="XMLFilter" class="org.springframework.integration.file.config.FileListFilterFactoryBean">
    <property name="filter" ref="XMLFileListFilter" />
    <property name="preventDuplicates" value="false" />
</bean>

<bean id="importFileComparator" class="com.example.demo.ImportFileComparator" />

<!--Input channel-->
<int-file:inbound-channel-adapter id="FilesInChannel"
        directory="file:C:/Users/USER/Desktop/SI-Failing"
        filter="XMLFilter"
        auto-startup="true">
    <int:poller fixed-rate="1000" time-unit="MILLISECONDS" max-messages-per-poll="1" />
</int-file:inbound-channel-adapter>

<!--Output channel-->
<int:recipient-list-router input-channel="FilesOutChannel"
    default-output-channel="FilesOutSuccessChannel" >
    <int:recipient channel="FilesOutFailureChannel" selector-expression="headers.containsKey('IMPORT_FAILURE')" />
</int:recipient-list-router>

<!--Success / Failure channel-->
<int-file:outbound-channel-adapter id="FilesOutSuccessChannel"
    directory="file:C:/Users/USER/Desktop/SI-Failing/success/" delete-source-files="true"
    filename-generator-expression="new java.text.SimpleDateFormat('yyyy-MM-dd_HH.mm.ss').format(new java.util.Date()) + '_' + payload.name"/>
<int-file:outbound-channel-adapter id="FilesOutFailureChannel"
    directory="file:C:/Users/USER/Desktop/SI-Failing/error" delete-source-files="true"
    filename-generator-expression="new java.text.SimpleDateFormat('yyyy-MM-dd_HH.mm.ss').format(new java.util.Date()) + '_' + payload.name"/>

<!--Verheiratung zwischen Importer, Input und Output-->
<int:service-activator
    ref="dataImporter"
    input-channel="FilesInChannel"
    output-channel="FilesOutChannel" />

这是导入处理程序:

public class DataImporter {

    public Message<File> handleFileImport(Message<File> message) {
        final File file = message.getPayload();
        System.out.println("Processing file " + file);
        return message;
    }
}

当将 3 个 XML 文件放入该文件夹时,将生成以下日志消息:

2018-05-09 13:47:34.989  INFO 6888 --- [ask-scheduler-5] 

o.s.i.file.FileReadingMessageSource      : Created message: [GenericMessage [payload=C:\Users\fischer\Desktop\SI-Failing\typeA_1.xml, headers={file_originalFile=C:\Users\fischer\Desktop\SI-Failing\typeA_1.xml, id=29b41c2e-3302-ca26-93a5-423f6f57fd4d, file_name=typeA_1.xml, file_relativePath=typeA_1.xml, timestamp=1525866454989}]]
Processing file C:\Users\fischer\Desktop\SI-Failing\typeA_1.xml
2018-05-09 13:47:35.986  INFO 6888 --- [ask-scheduler-3] o.s.i.file.FileReadingMessageSource      : Created message: [GenericMessage [payload=C:\Users\fischer\Desktop\SI-Failing\typeA_2.xml, headers={file_originalFile=C:\Users\fischer\Desktop\SI-Failing\typeA_2.xml, id=4fe71062-12b0-3649-56de-8c432ae2c6e4, file_name=typeA_2.xml, file_relativePath=typeA_2.xml, timestamp=1525866455986}]]
Processing file C:\Users\fischer\Desktop\SI-Failing\typeA_2.xml
2018-05-09 13:47:35.991 ERROR 6888 --- [ask-scheduler-3] o.s.integration.handler.LoggingHandler   : org.springframework.messaging.MessageHandlingException: failed to write Message payload to file; nested exception is java.nio.file.NoSuchFileException: C:\Users\fischer\Desktop\SI-Failing\typeA_2.xml, failedMessage=GenericMessage [payload=C:\Users\fischer\Desktop\SI-Failing\typeA_2.xml, headers={file_originalFile=C:\Users\fischer\Desktop\SI-Failing\typeA_2.xml, id=4fe71062-12b0-3649-56de-8c432ae2c6e4, file_name=typeA_2.xml, file_relativePath=typeA_2.xml, timestamp=1525866455986}]
    at org.springframework.integration.file.FileWritingMessageHandler.handleRequestMessage(FileWritingMessageHandler.java:590)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:158)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:181)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:160)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108)
    at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:200)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:158)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:181)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:160)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:426)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:336)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:227)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:158)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:132)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:181)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:160)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:108)
    at org.springframework.integration.endpoint.SourcePollingChannelAdapter.handleMessage(SourcePollingChannelAdapter.java:220)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:277)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.lambda$run$0(AbstractPollingEndpoint.java:378)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.lambda$execute$0(ErrorHandlingTaskExecutor.java:53)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:372)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.nio.file.NoSuchFileException: C:\Users\fischer\Desktop\SI-Failing\typeA_2.xml
    at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
    at sun.nio.fs.WindowsFileCopy.move(WindowsFileCopy.java:318)
    at sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:287)
    at java.nio.file.Files.move(Files.java:1395)
    at org.springframework.integration.file.FileWritingMessageHandler.rename(FileWritingMessageHandler.java:1030)
    at org.springframework.integration.file.FileWritingMessageHandler.handleFileMessage(FileWritingMessageHandler.java:626)
    at org.springframework.integration.file.FileWritingMessageHandler.handleRequestMessage(FileWritingMessageHandler.java:559)
    ... 55 more

似乎 spring 试图获取一个本身已经放入 success 文件夹中的文件,因此失败并出现 NoSuchFileException ... 我做错了什么?

如果需要,我可以提供一个 Spring Boot 演示应用程序:https://www.dropbox.com/s/7fwr9qi84c03u85/demo.7z?dl=0

最佳答案

您的问题出在 <property name="preventDuplicates" value="false" /> .

这样<int-file:inbound-channel-adapter>将能够在下一个轮询周期再次轮询同一文件。不过我发现没关系,因为你有 delete-source-files="true"两者<int-file:outbound-channel-adapter> 。所以,preventDuplicates选择并不是那么重要。

这是值得思考的一点。另一个我认为是罪魁祸首的是:fixed-rate="1000" 。当您长时间处理文件时,调度程序可能会启动新的轮询任务,因此可能会拾取相同的文件,因为您尚未到达 <int-file:outbound-channel-adapter>用于删除。考虑切换到fixed-delay="1000"相反。

更新

您的解决方案是这样的:

  <bean id="XMLFileListFilter" class="org.springframework.integration.file.filters.SimplePatternFileListFilter" >
    <constructor-arg value="*.xml" />
</bean>

<bean id="acceptOnceFileListFilter"
      class="org.springframework.integration.file.filters.FileSystemPersistentAcceptOnceFileListFilter">
    <constructor-arg>
        <bean class="org.springframework.integration.metadata.SimpleMetadataStore"/>
    </constructor-arg>
    <constructor-arg value="foo"/>
</bean>

<bean id="XMLFilter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
    <constructor-arg>
        <list>
            <ref bean="XMLFileListFilter"/>
            <ref bean="acceptOnceFileListFilter"/>
        </list>
    </constructor-arg>
</bean>

关注FileSystemPersistentAcceptOnceFileListFilter 。正如我在下面的一条评论中所说,最好不要传递同一文件,但它可以跟踪同一文件的修改。因此,您可以将同一文件的新版本放入该目录,只要其时间戳是最新的,该文件就会被 <int-file:inbound-channel-adapter> 拾取。 .

关于java - Spring Integration 抛出 NoSuchFileException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50252921/

相关文章:

java - 如何以相同的顺序遍历 SortedMap?

Java Swing,100个TextFields有类似的任务,所以我想编写一个函数来做到这一点

Java无法打开IntelliJ构建的jar

java - java RMI 远程对象(服务器)是单例吗?

Spring OAuth2 禁用 TokenEndpoint 的 HTTP 基本身份验证

java - 集合$UnmodifyingRandomAccessList<E> Cassandra 冰雪奇缘 map

java - 来自现有 wsdl 的带有 spring-boot 和 mtom 的 SOAP 服务

java - 在自定义链表上使用 ListIterator

java - Spring-Data-Jpa 中一对多映射的 JSON 结果错误

java - CrudRepository 保存方法不返回更新后的实体