스프링 배치 jobParameter 중 필수값을 지정해야하는 파라미터가 존재하였습니다.
null이 입력되면 배치를 종료처리 해야할지 고민하던 찰나에 이런 경우를 위한 Validator가 있다는 것을 알게 되었습니다
방법은 다음과 같습니다.
JobParametersValidator를 구현한 CustomJobParametersValidator를 생성합니다.
public class CustomJobParametersValidator implements JobParametersValidator {
@Override
public void validate(JobParameters jobParameters) throws JobParametersInvalidException {
if (jobParameters.getString("name") == null) { // name이란 parameter가 없으면 예외 발생
throw new JobParametersInvalidException("name parameter is not found.");
}
}
}
이후 스프링 job 설정에서 validator로 위에서 생성한 CustomJobParametersValidator을 설정합니다.
@RequiredArgsConstructor
@Configuration
public class ValidatorConfiguration {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job parametersValidatorJob() {
return this.jobBuilderFactory.get("parametersValidatorJob")
.validator(new CustomJobParametersValidator()) // Validator 설정
.start(parametersValidatorStep1())
.next(parametersValidatorStep2())
.next(parametersValidatorStep3())
.build();
}
...
}
DefaultJobParametersValidator 구현체에 requiredKeys, optionalKeys 값을 넘겨 필수 파라미터와 옵션 파라미터를 구분할 수 있도록 합니다.
@Bean(name = JOB_NAME)
public Job job() throws Exception {
String[] requiredKeys = {"chnlId", "critnDts"}; // 필수 파라미터명
String[] optionalKeys = {"run.id", "stdCtgId", "strtDt", "endDt"}; // 옵션 파라미터명 run.id는 incrementer로 생성되는 값임
return jobBuilderFactory.get(JOB_NAME)
.validator(new DefaultJobParametersValidator(requiredKeys, optionalKeys))
.incrementer(new UniqueRunIdIncrementer())
.listener(jobExecutionListener())
.start(startStep())
.build();
}
jobBuilderFactory로 job을 생성할때 validator로 DefaultJobParametersValidator을 지정하면 다음과 같은 validate함수가 호출됩니다.
@Override
public void validate(@Nullable JobParameters parameters) throws JobParametersInvalidException {
if (parameters == null) {
throw new JobParametersInvalidException("The JobParameters can not be null");
}
Set<String> keys = parameters.getParameters().keySet();
// If there are explicit optional keys then all keys must be in that
// group, or in the required group.
if (!optionalKeys.isEmpty()) {
Collection<String> missingKeys = new HashSet<>();
for (String key : keys) {
if (!optionalKeys.contains(key) && !requiredKeys.contains(key)) { // 옵션키에도 존재하지 않고 필수키에도 존재하지 않으면 -> 지정된 키가 아니면 예외 발생
missingKeys.add(key);
}
}
if (!missingKeys.isEmpty()) {
throw new JobParametersInvalidException(
"The JobParameters contains keys that are not explicitly optional or required: " + missingKeys);
}
}
Collection<String> missingKeys = new HashSet<>();
for (String key : requiredKeys) {
if (!keys.contains(key)) { // 필수키가 존재하지 않으면 예외 발생
missingKeys.add(key);
}
}
if (!missingKeys.isEmpty()) {
throw new JobParametersInvalidException("The JobParameters do not contain required keys: " + missingKeys);
}
}

필수키를 인자로 넘겨주지 않으면 예외를 발생시키고 배치가 종료되는 것을 확인할 수 있었습니다.