don't dream your life, live your dreams !
Here is a short example about Spring Batch that show how to convert a csv file to an xml file.
Contents
If you use maven, add this to your pom.xml
<dependencies> (...) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-batch</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> </dependency> (...) </dependencies> |
Buisness team have the following csv file named users.csv :
10,John,Doe 20,Jane,Doe 30,Albert,Einstein |
We can see that :
Let’s deal with the following implementation :
import javax.xml.bind.annotation.XmlRootElement; import lombok.Data; @Data @XmlRootElement(name = "user") public class User { private Integer id; private String lastName; private String firstName; } |
The batch processor allows you to make any operation about your model.
For example, you can uppercase all last names.
You have to return a new model object, so this batch processor is immutable).
In the example we only diplay the processed user in the LOGGER::info appender.
import org.springframework.batch.item.ItemProcessor; import lombok.extern.slf4j.Slf4j; @Slf4j public class UserItemProcessor implements ItemProcessor<User, User> { @Override public User process(final User user) throws Exception { LOGGER.info("User processed : {}", user); return user; } } |
You can implement a listener to handle ‘before’ and ‘after’ jobs execution.
import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.listener.JobExecutionListenerSupport; import org.springframework.stereotype.Component; import lombok.extern.slf4j.Slf4j; @Component @Slf4j public class JobCompletionNotificationListener extends JobExecutionListenerSupport { @Override public void beforeJob(JobExecution jobExecution) { LOGGER.info("Before job process..."); } @Override public void afterJob(JobExecution jobExecution) { LOGGER.info("After job process..."); if(jobExecution.getStatus() == BatchStatus.COMPLETED) { LOGGER.info("Job completed."); } } } |
Now let’s configure our batch :
import java.io.File; import javax.inject.Inject; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; import org.springframework.batch.item.xml.StaxEventItemWriter; import org.springframework.batch.item.xml.builder.StaxEventItemWriterBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.oxm.Marshaller; import org.springframework.oxm.jaxb.Jaxb2Marshaller; @Configuration @EnableBatchProcessing public class BatchConfiguration { @Inject public JobBuilderFactory jobBuilderFactory; @Inject public StepBuilderFactory stepBuilderFactory; /** * Read csv file. * @return FlatFileItemReader */ @Bean public FlatFileItemReader<User> reader() { BeanWrapperFieldSetMapper<User> bean = new BeanWrapperFieldSetMapper<>(); bean.setTargetType(User.class); return new FlatFileItemReaderBuilder<User>() .name("userItemReader") .resource(new ClassPathResource("users.csv")) .delimited() .names(new String[]{"id" , "firstName", "lastName"}) .fieldSetMapper(bean) .build(); } @Bean public UserItemProcessor processor() { return new UserItemProcessor(); } @Bean public Marshaller marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setClassesToBeBound(User.class); return marshaller; } /** * Write result to xml file. * @return StaxEventItemWriter */ @Bean public StaxEventItemWriter<User> writer() { return new StaxEventItemWriterBuilder<User>() .name("userItemWriter") .resource(new FileSystemResource(new File(TEMP_DIR,"users.xml"))) .marshaller(marshaller()) .rootTagName("users") .build(); } @Bean public Job csvToXmlJob() { return jobBuilderFactory .get("csvToXmlJob") .flow(step1()) .end() .build(); } @Bean public Step step1() { return stepBuilderFactory .get("step1") .<User, User>chunk(10) .reader(reader()) .writer(writer()) .processor(processor()) .build(); } } |
To run the job, you can do like this :
@Component public final class JobComponent { @Inject JobLauncher jobLauncher; @Inject Job job; @RequestMapping("/runMyJob") public void runMyJob() throws Exception { jobLauncher.run(job, new JobParameters()); } } |
<?xml version="1.0" encoding="UTF-8"?> <users> <user> <id>10</id> <lastName>Doe</lastName> <firstName>John</firstName> </user> <user> <id>20</id> <lastName>Doe</lastName> <firstName>Jane</firstName> </user> <user> <id>30</id> <lastName>Einstein</lastName> <firstName>Albert</firstName> </user> </users> |
Copyright © 2024 My linux world - by Marc RABAHI
Design by Marc RABAHI and encelades.
admin