예제로 배우는 핵심 Spring Batch

Ch03. 배치 실행 시 파라미터 (파일 이름) 받기 및 (csv)검증

webmaster 2023. 6. 7. 00:04
728x90

https://docs.spring.io/spring-batch/docs/current/reference/html/job.html#jobparametersvalidator

 

Configuring and Running a Job

Because the script launching the job must kick off a Java Virtual Machine, there needs to be a class with a main method to act as the primary entry point. Spring Batch provides an implementation that serves this purpose: CommandLineJobRunner. Note that thi

docs.spring.io

파라미터로 파일명 전달받기

/**
 * desc: 파일 이름 파라미터 전달 그리고 검증
 * run: --spring.batch.job.name=validatedParamJob -fileName=test.csv
 */
@Configuration
@RequiredArgsConstructor
public class ValidatedParamJobConfig {
  private final JobBuilderFactory jobBuilderFactory;

  private final StepBuilderFactory stepBuilderFactory;

  @Bean
  public Job validatedParamJob(Step validatedParamStep){
    return jobBuilderFactory.get("validatedParamJob")
        .incrementer(new RunIdIncrementer())
        .start(validatedParamStep)
        .build();
  }

  @Bean
  @JobScope
  public Step validatedParamStep(Tasklet validatedParamTasklet) {
    return stepBuilderFactory.get("validatedParamStep")
        .tasklet(validatedParamTasklet) //읽고 쓰고 할 데이터가 없을 때 사용
        .build();
  }

  @Bean
  @StepScope
  public Tasklet validatedParamTasklet( @Value("#{jobParameters['fileName']}") String fileName) {
    return new Tasklet() {
      @Override
      public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
          throws Exception {
        System.out.println("Validated Param Tasklet");
        System.out.println(fileName);
        return RepeatStatus.FINISHED;
      }
    };
  }
}
  • 스프링에서 제공하는 @Value 어노테이션을 통해 Argument로 전달한 파일 이름을 읽을 수 있다.
  • #{jobParameters}를 통해 job 파라미터로 등록하고 사용할 수 있다.

단일 Validator 등록하기

ValidatedParamJobConfig

/**
 * desc: 파일 이름 파라미터 전달 그리고 검증
 * run: --spring.batch.job.name=validatedParamJob -fileName=test.csv
 */
@Configuration
@RequiredArgsConstructor
public class ValidatedParamJobConfig {
  private final JobBuilderFactory jobBuilderFactory;

  private final StepBuilderFactory stepBuilderFactory;

  @Bean
  public Job validatedParamJob(Step validatedParamStep){
    return jobBuilderFactory.get("validatedParamJob")
        .incrementer(new RunIdIncrementer())
        .validator(new FileParamValidator()) //스프링 배치에서는 Job에서 검증을 지원한다. //단일 등록
        .start(validatedParamStep)
        .build();
  }


  @Bean
  @JobScope
  public Step validatedParamStep(Tasklet validatedParamTasklet) {
    return stepBuilderFactory.get("validatedParamStep")
        .tasklet(validatedParamTasklet) //읽고 쓰고 할 데이터가 없을 때 사용
        .build();
  }

  @Bean
  @StepScope
  public Tasklet validatedParamTasklet( @Value("#{jobParameters['fileName']}") String fileName) {
    return new Tasklet() {
      @Override
      public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
          throws Exception {
        System.out.println("Validated Param Tasklet");
        //System.out.println(fileName);

        return RepeatStatus.FINISHED;
      }
    };
  }
}

FileParamValidator

public class FileParamValidator implements JobParametersValidator {
  @Override
  public void validate(JobParameters parameters) throws JobParametersInvalidException {
    //검증이 필요한 로직 작성
    String fileName = parameters.getString("fileName");

    if(!StringUtils.endsWithIgnoreCase(fileName, "csv")){ //csv가 아닐 경우
      //예외 발생
      throw new JobParametersInvalidException("This is not csv file");
    }
    //이상 없을 경우 validate 종료
  }
}
  • Tasklet에서 검증시키는 것이 아닌, Job에서 검증을 하여 예외를 발생시켜야 한다 
    • 만약 파라미터가 잘못되었다면, Job 자체를 실행시키면 안 되기 때문에 job을 생성시켜 주는 factory에서 validator를 추가하는 메서드가 있다.
  • JobParametersValidator를 구현한 FileParamValidator 클래스를 생성한다.
  • validate를 오버라이드하면 되는데, 이때 검증하고 싶은 로직이 있다면, 해당 메서드에서 예외를 발생시키면 된다.
    • 여기서는 파일명이 "csv"로 끝나지 않는다면, JobParametersInvalidException을 발생시켰다.
    • 이상이 없을 경우 예외를 발생시키지 않으면 된다.(파일명이 "csv"로 끝나면, if문을 타지 않고 예외를 발생시키지 않는다)

다중 Validator 등록

/**
 * desc: 파일 이름 파라미터 전달 그리고 검증
 * run: --spring.batch.job.name=validatedParamJob -fileName=test.csv
 */
@Configuration
@RequiredArgsConstructor
public class ValidatedParamJobConfig {
  private final JobBuilderFactory jobBuilderFactory;

  private final StepBuilderFactory stepBuilderFactory;

  @Bean
  public Job validatedParamJob(Step validatedParamStep){
    return jobBuilderFactory.get("validatedParamJob")
        .incrementer(new RunIdIncrementer())
        //.validator(new FileParamValidator()) //스프링 배치에서는 Job에서 검증을 지원한다. //단일 등록
        .validator(multipleValidator()) //다중 validator 등록
        .start(validatedParamStep)
        .build();
  }

  private CompositeJobParametersValidator multipleValidator(){
    CompositeJobParametersValidator validator = new CompositeJobParametersValidator();
    validator.setValidators(Arrays.asList(new FileParamValidator()));
    return validator;
  }

  @Bean
  @JobScope
  public Step validatedParamStep(Tasklet validatedParamTasklet) {
    return stepBuilderFactory.get("validatedParamStep")
        .tasklet(validatedParamTasklet) //읽고 쓰고 할 데이터가 없을 때 사용
        .build();
  }

  @Bean
  @StepScope
  public Tasklet validatedParamTasklet( @Value("#{jobParameters['fileName']}") String fileName) {
    return new Tasklet() {
      @Override
      public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
          throws Exception {
        System.out.println("Validated Param Tasklet");
        //System.out.println(fileName);

        return RepeatStatus.FINISHED;
      }
    };
  }
}
  • validator를 다중으로 등록하기 위해서는 CompositeJobParametersValidator 타입을 validator를 넣어 주어야 한다.
  • 해당 인스턴스를 생성 후, setValidators 메서드를 통해 List 형식으로 Validator를 추가할 수 있다
    • 여기서는 한 개만 추가했다..
  • 생성한 CompositeJobParametersValidator를 validator 메서드 인자로 전달해 주면 된다.
728x90