我有多个文件可以从具有相同父路径的两个不同目录中读取和写入。 如果其中一个目录没有要读取的文件,是否可以在“org.springframework.batch.item.file。 MultiResourceItemReader ”中选择特定目录?
<!-- multi xml reader -->
<bean id="multiResourceReader" class="org.springframework.batch.item.file.MultiResourceItemReader">
<property name="resources" ref="vinFeedFileResouce" />
<property name="delegate" ref="vinFeedReader" />
</bean>
<bean id="vinFeedFileResouce" class="org.springframework.core.io.FileSystemResource" scope="step">
<constructor-arg>
<list>
<ref bean="read_ONE" />
<ref bean="read_TWO" />
</list>
</constructor-arg>
</bean>
<bean id="read_ONE" class="org.springframework.core.io.FileSystemResource" scope="step">
<constructor-arg value="#{path_ONE}"></constructor-arg>
</bean>
<bean id="read_TWO" class="org.springframework.core.io.FileSystemResource" scope="step">
<constructor-arg value="#{path_TWO}"></constructor-arg>
</bean>
我为读者收到以下错误:
[pool-1-thread-1](batch.listener.ModelMasterFailureListener:13)-Encountered error on Model master read
org.springframework.batch.item.ItemStreamException: Failed to initialize the reader
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:137)
at org.springframework.batch.item.file.MultiResourceItemReader.read(MultiResourceItemReader.java:105)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:90)
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:87)
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:108)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:214)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:103)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:68)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:386)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:264)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:76)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:214)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:250)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:48)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:114)
at com.ahm.ngt.cbo.feed.batch.scheduler.RunScheduler.run(RunScheduler.java:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
at org.springframework.scheduling.support.MethodInvokingRunnable.run(MethodInvokingRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'scopedTarget.vinFeedFileResouce' defined in class path resource [spring/batch/jobs/ca-vin-feed-config.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.io.File]: Could not convert constructor argument value of type [java.util.ArrayList] to required type [java.io.File]: Failed to convert value of type 'java.util.ArrayList' to required type 'java.io.File'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.util.ArrayList] to required type [java.io.File]: PropertyEditor [org.springframework.beans.propertyeditors.FileEditor] returned inappropriate value
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:702)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:329)
at org.springframework.batch.core.scope.StepScope.get(StepScope.java:150)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:33)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:184)
at com.sun.proxy.$Proxy1.exists(Unknown Source)
at org.springframework.batch.item.xml.StaxEventItemReader.doOpen(StaxEventItemReader.java:187)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:134)
... 45 more
答案 0 :(得分:0)
如果您看到FileSystemResource
的源代码,您会发现构造函数可以采用文件或字符串而不是文件列表或字符串。您可以编写自定义资源阅读器来读取多个目录中的文件。这是一个例子
<bean id="multiResourceReader" class="org.springframework.batch.item.file.MultiResourceItemReader">
<property name="resources" value="#{myResourceReader.read()}" />
<property name="delegate" ref="vinFeedReader" />
</bean>
<bean id="myResourceReader" class="com.kp.swasthik.MyResourceReader">
<property name="resource" value="file:///path1/*.txt, file:///path2/*.txt"></property>
</bean>
ResourceReader类。
public class MyResourceReader {
private String resource;
public String getResource() {
return resource;
}
public void setResource(String resource) {
this.resource = resource;
}
public Resource[] read(){
List<Resource> resources = new ArrayList<>();
if(resource == null || resource.isEmpty()){
return new Resource[]{};
}
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Arrays.stream(resource.split(",")).forEach(v->{
try {
Collections.addAll(resources, resolver.getResources(v));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
return resources.toArray(new Resource[0]);
}
}
答案 1 :(得分:0)
切换到基于注释的配置。在那里,您可以将所有资源(来自不同的目录)添加到读者:
@Bean
public ItemReader<?> reader() {
Resource[] res = ... //get eg using PathMatchingResourcePatternResolver multiple times on different dirs
MultiResourceItemReader<?> r = new MultiResourceItemReader<>();
r.setResources(res);
return r;
}