In this post, we will show you how to configure a Spring Batch job to read data from a CSV file and write into XML file.
Project structure
This is a directory structure of the standard gradle project.
Project dependencies
task wrapper(type: Wrapper) { gradleVersion = '3.2.1' } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' sourceCompatibility = 1.8 repositories { mavenLocal() mavenCentral() } dependencies { compile 'org.springframework:spring-oxm:4.3.7.RELEASE' compileOnly('org.projectlombok:lombok:1.16.12') compile('org.springframework.boot:spring-boot-starter-batch:1.5.2.RELEASE') testCompile('org.springframework.boot:spring-boot-starter-test:1.5.2.RELEASE') } buildscript { repositories { mavenLocal() jcenter() } dependencies { classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.2.RELEASE" } }
application.properties file
#empty
Spring Batch Jobs
CSV file
100,Walking Techie,CS 101,John Doe,CS 102,Sachin Tendulkar,CS
Create a job which will read CSV file and write into XML file.
package com.walking.techie.csvtoxml.jobs; import com.walking.techie.csvtoxml.model.Student; import com.walking.techie.csvtoxml.processor.StudentProcessor; import java.util.HashMap; import java.util.Map; 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.mapping.BeanWrapperFieldSetMapper; import org.springframework.batch.item.file.mapping.DefaultLineMapper; import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; import org.springframework.batch.item.xml.StaxEventItemWriter; import org.springframework.beans.factory.annotation.Autowired; 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.xstream.XStreamMarshaller; @Configuration @EnableBatchProcessing public class BatchConfiguration { @Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Bean public Job CsvToXmlJob() { return jobBuilderFactory.get("CsvToXmlJob").flow(step1()).end().build(); } @Bean public Step step1() { return stepBuilderFactory.get("step1").<Student, Student>chunk(10).reader(reader()) .writer(writer()).processor(processor()).build(); } @Bean public StudentProcessor processor() { return new StudentProcessor(); } @Bean public FlatFileItemReader<Student> reader() { FlatFileItemReader<Student> reader = new FlatFileItemReader<>(); reader.setResource(new ClassPathResource("student.csv")); reader.setLineMapper(new DefaultLineMapper<Student>() {{ setFieldSetMapper(new BeanWrapperFieldSetMapper<Student>() {{ setTargetType(Student.class); }}); setLineTokenizer(new DelimitedLineTokenizer() {{ setNames(new String[]{"rollNo", "name", "department"}); }}); }}); return reader; } @Bean public StaxEventItemWriter<Student> writer() { StaxEventItemWriter<Student> writer = new StaxEventItemWriter<>(); writer.setResource(new FileSystemResource("xml/student.xml")); writer.setMarshaller(studentUnmarshaller()); writer.setRootTagName("students"); return writer; } @Bean public XStreamMarshaller studentUnmarshaller() { XStreamMarshaller unMarshaller = new XStreamMarshaller(); Map<String, Class> aliases = new HashMap<String, Class>(); aliases.put("student", Student.class); unMarshaller.setAliases(aliases); return unMarshaller; } }
Map XML file values to Student
object and write to XML file.
A Java model class
package com.walking.techie.csvtoxml.model; import lombok.Data; import lombok.ToString; @Data @ToString public class Student { private Integer rollNo; private String name; private String department; }
A custom student processor class that will process each and every Student
object.
package com.walking.techie.csvtoxml.processor; import com.walking.techie.csvtoxml.model.Student; import lombok.extern.slf4j.Slf4j; import org.springframework.batch.item.ItemProcessor; @Slf4j public class StudentProcessor implements ItemProcessor<Student, Student> { @Override public Student process(Student item) throws Exception { log.info("Student processed : " + item); return item; } }
Run Application
package com.walking.techie; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Output
Output of the application will store in csv/student.csv
<?xml version="1.0" encoding="UTF-8"?><students><student><rollNo>100</rollNo><name>Walking Techie</name><department>CS</department></student><student><rollNo>101</rollNo><name>John Doe</name><department>CS</department></student><student><rollNo>102</rollNo><name>Sachin Tendulkar</name><department>CS</department></student></students>
output on console
2017-03-26 19:12:52.791 INFO 5892 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=CsvToXmlJob]] launched with the following parameters: [{}] 2017-03-26 19:12:52.810 INFO 5892 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [step1] 2017-03-26 19:12:52.843 INFO 5892 --- [ main] c.w.t.c.processor.StudentProcessor : Student processed : Student(rollNo=100, name=Walking Techie, department=CS) 2017-03-26 19:12:52.843 INFO 5892 --- [ main] c.w.t.c.processor.StudentProcessor : Student processed : Student(rollNo=101, name=John Doe, department=CS) 2017-03-26 19:12:52.843 INFO 5892 --- [ main] c.w.t.c.processor.StudentProcessor : Student processed : Student(rollNo=102, name=Sachin Tendulkar, department=CS) 2017-03-26 19:12:52.876 INFO 5892 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=CsvToXmlJob]] completed with the following parameters: [{}] and the following status: [COMPLETED]
Note : This code has been compiled and run on mac notebook and intellij IDEA.
Nice Article. Helpful
ReplyDeleteCan we pretty print the XML content in the file?
ReplyDelete