2013-07-04 3 views
1

스프링 배치 작업 실행을 통해 플랫 파일을 처리해야한다는 요구 사항이 있습니다. 처리해야 할 폴더에서 파일 목록을 가져옵니다. 이 작업을 수행하는 방법을 알려주십시오.스프링 배치 작업 실행을위한 리소스 목록

예를 들어

:
나는 폴더에 player.csvplayer1.csvplayer2.csv 있습니다. 이 파일 이름이 목록에 있습니다. 단일 작업을 실행할 수 있도록 작업 매개 변수의 모든 파일 이름을 입력 할 수 있는지 알려주십시오.

JobParameters jobParameters = new JobParametersBuilder().addString("input.file", "file:player.csv").toJobParameters(); 
JobExecution execution = jobLauncher.run(job,jobParameters); 
assertEquals(ExitStatus.COMPLETED, execution.getExitStatus()); 

답변

2

여기에는 몇 가지 방법이 있습니다. 1. 한 번에 하나의 파일을 처리하고 작업 초기화 프로그램이 파일을 반복하고 작업을 트리거하여 한 번에 하나의 파일 만 전달하는 작업을 만듭니다. 2. 작업 내에서 '루프'를 생성하여 값을 입력하고 각 파일을 처리하십시오.

다음은 후자 옵션의 예입니다.

먼저 작업 구성 - 처리 할 파일의 실행 컨텍스트 값을 결정하기 위해 결정자를 사용합니다. 합니다 (jobParameter에서) 더 이상 파일이없는 경우, 그때는 여기

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:batch="http://www.springframework.org/schema/batch" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd"> 

    <batch:job id="multipleFileProcess"> 
     <batch:decision decider="decider" id="multipleFileProcess.decider"> 
      <batch:next on="UNKNOWN" to="multipleFileProcess.step1"/> 
      <batch:end on="COMPLETED"/> 
     </batch:decision> 
     <batch:step id="multipleFileProcess.step1" next="multipleFileProcess.decider"> 
      <batch:tasklet> 
       <batch:chunk reader="fileReader" writer="outWriter" commit-interval="10"/> 
      </batch:tasklet> 
     </batch:step> 
     <batch:validator> 
      <bean class="org.springframework.batch.core.job.DefaultJobParametersValidator"> 
       <property name="requiredKeys" value="input.files"/> 
      </bean>   
     </batch:validator> 
    </batch:job> 


    <bean id="fileReader" 
     class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"> 
     <property name="lineMapper" ref="lineMapper"/> 
     <property name="resource" value="file:#{jobExecutionContext['input.file']}"/> 
    </bean> 

    <bean id="lineMapper" 
     class="org.springframework.batch.item.file.mapping.PassThroughLineMapper"/> 


    <bean id="transactionManager" 
     class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"> 
    </bean> 

    <bean id="decider" class="de.incompleteco.spring.batch.decider.FileDecision"/> 

    <bean id="outWriter" class="de.incompleteco.spring.batch.item.writer.SystemOutItemWriter"/> 

</beans> 

내부 큐를 사용하여 결정자 코드 (의 완료 - 아마 실행 컨텍스트의 문자열이 '큐'를 유지하는 것이 더 안전 할 것 천천히 (수동 '팝'문자열의 항목을 -하지만 민첩 큐 사용) 단축 것을

package de.incompleteco.spring.batch.decider; 

import java.util.Arrays; 
import java.util.Queue; 
import java.util.concurrent.LinkedBlockingQueue; 

import org.springframework.batch.core.JobExecution; 
import org.springframework.batch.core.StepExecution; 
import org.springframework.batch.core.job.flow.FlowExecutionStatus; 
import org.springframework.batch.core.job.flow.JobExecutionDecider; 

public class FileDecision implements JobExecutionDecider { 

    public static final String INPUT_FILE = "input.file"; 
    public static final String INPUT_FILES = "input.files"; 
    public static final String DELIMITER = ","; 

    private Queue<String> inputFiles; 

    @Override 
    public FlowExecutionStatus decide(JobExecution jobExecution,StepExecution stepExecution) { 
     //check if the jobExecution has the input.file in it's context 
     if (!jobExecution.getExecutionContext().containsKey(INPUT_FILE)) { 
      //build the queue 
      inputFiles = new LinkedBlockingQueue<String>(Arrays.asList(jobExecution.getJobParameters().getString(INPUT_FILES).split(DELIMITER))); 
     }//end if 
     //pop and add 
     String file = inputFiles.poll(); 
     if (file != null) { 
      jobExecution.getExecutionContext().put(INPUT_FILE, file); 
      return FlowExecutionStatus.UNKNOWN; 
     }//end if 
     //return 'done' 
     return FlowExecutionStatus.COMPLETED; 
    } 

} 

여기 더미 '작가'의 밖으로

package de.incompleteco.spring.batch.item.writer; 

import java.util.List; 

import org.springframework.batch.item.ItemWriter; 

public class SystemOutItemWriter implements ItemWriter<String> { 

    @Override 
    public void write(List<? extends String> items) throws Exception { 
     for (String item : items) { 
      System.out.println("this is what was received:" + item); 
     }//end for 
    } 

} 
서면 '로 파일을 보여이야을

그리고 마지막으로이 장치가 실행되는지 확인하기위한 단위 테스트

package de.incompleteco.spring.batch; 

import static org.junit.Assert.assertFalse; 

import java.io.File; 
import java.io.FileWriter; 

import javax.annotation.Resource; 

import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.TemporaryFolder; 
import org.junit.runner.RunWith; 
import org.springframework.batch.core.Job; 
import org.springframework.batch.core.JobExecution; 
import org.springframework.batch.core.JobParameters; 
import org.springframework.batch.core.JobParametersBuilder; 
import org.springframework.batch.core.explore.JobExplorer; 
import org.springframework.batch.core.launch.JobLauncher; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

import de.incompleteco.spring.batch.decider.FileDecision; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("classpath:/META-INF/spring/*-context.xml") 
public class MultipleFileProcessIntegrationTest { 

    @Rule 
    public TemporaryFolder folder = new TemporaryFolder(); 

    @Resource 
    private Job job; 

    @Resource 
    private JobLauncher jobLauncher; 

    @Resource 
    private JobExplorer jobExplorer; 

    @Test 
    public void test() throws Exception { 
     //somewhere to hold the filenames 
     StringBuilder builder = new StringBuilder(); 
     //create 3 files 
     for (int i=0;i<3;i++) { 
      File file = folder.newFile("testfile" + i + ".txt"); 
      //write some content 
      FileWriter writer = new FileWriter(file); 
      writer.write("test content: " + i); 
      writer.flush(); 
      writer.close(); 
      //add the filename 
      if (i > 0) { 
       builder.append(FileDecision.DELIMITER); 
      }//end if 
      builder.append(file.getAbsolutePath()); 
      //show it 
      System.out.println(file.getAbsolutePath()); 
     }//end loop 


     //now build the job parameters 
     JobParameters parameters = new JobParametersBuilder().addString(FileDecision.INPUT_FILES,builder.toString()).toJobParameters(); 
     //execution 
     JobExecution execution = jobLauncher.run(job,parameters); 
     //check 
     while (jobExplorer.getJobExecution(execution.getId()).isRunning()) { 
      Thread.sleep(100); 
     }//end while 
     //load 
     execution = jobExplorer.getJobExecution(execution.getId()); 
     //check 
     assertFalse(execution.getStatus().isUnsuccessful()); 
    } 

} 
+1

+1 결정자에 대해. – Cygnusx1

관련 문제