2017-04-25 124 views
0

我有兩個不同的目錄有相同的父路徑讀取和寫入多個文件。 如果其中一個目錄沒有要讀取的文件,是否可以在「org.springframework.batch.item.file。MultiResourceItemReader」中選擇特定目錄?如何從Spring中的兩個不同文件夾讀取多個xml文件?

<!-- 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

如果你看到的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]); 
    } 

} 
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; 
} 
相關問題