In this example, we’ll see how to make the call to REST API and feed that information into the reader.
Student.java
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class Student {
private String emailAddress;
private String name;
private String purchasedPackage;
}
SpringBatchJob.java
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.web.client.RestTemplate;
@Configuration
public class SpringBatchExampleJobConfig {
private static final String PROPERTY_REST_API_URL = "rest.api.url";
@Bean
public ItemReader<Student> itemReader(Environment environment, RestTemplate restTemplate) {
return new RESTStudentReader(environment.getRequiredProperty(PROPERTY_REST_API_URL), restTemplate);
}
@Bean
public ItemWriter<Student> itemWriter() {
return new LoggingItemWriter();
}
@Bean
public Step exampleJobStep(ItemReader<Student> reader,
ItemWriter<Student> writer,
StepBuilderFactory stepBuilderFactory) {
return stepBuilderFactory.get("exampleJobStep")
.<Student, Student>chunk(10)
.reader(reader)
.writer(writer)
.build();
}
@Bean
public Job exampleJob(Step exampleJobStep,
JobBuilderFactory jobBuilderFactory) {
return jobBuilderFactory.get("exampleJob")
.incrementer(new RunIdIncrementer())
.flow(exampleJobStep)
.end()
.build();
}
}
RestStudentReader.java
class RESTStudentReader implements ItemReader<Student> {
private static final Logger LOGGER = LoggerFactory.getLogger(RESTStudentReader.class);
private final String apiUrl;
private final RestTemplate restTemplate;
private int nextStudentIndex;
private List<Student> studentData;
RESTStudentReader(String apiUrl, RestTemplate restTemplate) {
this.apiUrl = apiUrl;
this.restTemplate = restTemplate;
nextStudentIndex = 0;
}
@Override
public Student read() throws Exception {
LOGGER.info("Reading the information of the next student");
if (studentDataIsNotInitialized()) {
studentData = fetchStudentDataFromAPI();
}
Student nextStudent = null;
if (nextStudentIndex < studentData.size()) {
nextStudent = studentData.get(nextStudentIndex);
nextStudentIndex++;
}
else {
nextStudentIndex = 0;
studentData = null;
}
LOGGER.info("Found student: {}", nextStudent);
return nextStudent;
}
private boolean studentDataIsNotInitialized() {
return this.studentData == null;
}
private List<Student> fetchStudentDataFromAPI() {
LOGGER.debug("Fetching student data from an external API by using the url: {}", apiUrl);
ResponseEntity<Student[]> response = restTemplate.getForEntity(apiUrl, Student[].class);
Student[] studentData = response.getBody();
LOGGER.debug("Found {} students", studentData.length);
return Arrays.asList(studentData);
}
}
LoggingWriter.java
public class LoggingItemWriter implements ItemWriter<Student> {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingItemWriter.class);
@Override
public void write(List<? extends Student> list) throws Exception {
LOGGER.info(">>>> Writing students: {}", list);
}
}
LoggingItemWriter.java
public class LoggingItemWriter implements ItemWriter<Student> {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingItemWriter.class);
@Override
public void write(List<? extends Student> list) throws Exception {
LOGGER.info(">>>> Writing students: {}", list);
}
}
MainApp.java
@SpringBootApplication
@EnableBatchProcessing
@EnableScheduling
public class SpringBatchExampleApplication implements CommandLineRunner {
@Autowired
private Job job;
@Autowired
private JobLauncher jobLauncher;
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(SpringBatchExampleApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
jobLauncher.run(job, newExecution());
}
private JobParameters newExecution() {
Map<String, JobParameter> parameters = new HashMap<>();
JobParameter parameter = new JobParameter(new Date());
parameters.put("currentTime", parameter);
return new JobParameters(parameters);
}
}
StudentController.java
@RestController
@RequestMapping("/api/student")
public class StudentController {
private static final Logger LOGGER = LoggerFactory.getLogger(StudentController.class);
@RequestMapping(method = RequestMethod.GET)
public List<Student> findStudents() {
LOGGER.info("Finding all students");
List<Student> students = createStudents();
LOGGER.info("Found {} students", students.size());
return students;
}
private List<Student> createStudents() {
Student tony = new Student();
tony.setEmailAddress("tony.tester@gmail.com");
tony.setName("Tony Tester");
tony.setPurchasedPackage("master");
Student nick = new Student();
nick.setEmailAddress("nick.newbie@gmail.com");
nick.setName("Nick Newbie");
nick.setPurchasedPackage("starter");
Student ian = new Student();
ian.setEmailAddress("ian.intermediate@gmail.com");
ian.setName("Ian Intermediate");
ian.setPurchasedPackage("intermediate");
return Arrays.asList(tony, nick, ian);
}
}