In this post, we will show you how to configure a Spring Batch job to read data from a XML file and write into CSV 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
XML file
<?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>
Create a job which will read XML file and write into CSV file.
package com.walking.techie.xmltocsv.jobs;
import com.walking.techie.xmltocsv.model.Student;
import com.walking.techie.xmltocsv.processor.StudentProcessor;
import java.util.HashMap;
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.FlatFileItemWriter;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.DelimitedLineAggregator;
import org.springframework.batch.item.xml.StaxEventItemReader;
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.Unmarshaller;
import org.springframework.oxm.xstream.XStreamMarshaller;
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Job XmlToCsvJob() {
return jobBuilderFactory.get("XmlToCsvJob").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 StaxEventItemReader<Student> reader() {
StaxEventItemReader<Student> reader = new StaxEventItemReader<>();
reader.setResource(new ClassPathResource("student.xml"));
reader.setFragmentRootElementName("student");
reader.setUnmarshaller(unMarshaller());
return reader;
}
public Unmarshaller unMarshaller() {
XStreamMarshaller unMarshal = new XStreamMarshaller();
unMarshal.setAliases(new HashMap<String, Class>() {{
put("student", Student.class);
}});
return unMarshal;
}
@Bean
public FlatFileItemWriter<Student> writer() {
FlatFileItemWriter<Student> writer = new FlatFileItemWriter<>();
writer.setResource(new FileSystemResource("csv/student.csv"));
writer.setLineAggregator(new DelimitedLineAggregator<Student>() {{
setDelimiter(",");
setFieldExtractor(new BeanWrapperFieldExtractor<Student>() {{
setNames(new String[]{"rollNo", "name", "department"});
}});
}});
return writer;
}
}
Map XML file values to Student object and write to CSV file.
A Java model class
package com.walking.techie.xmltocsv.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.xmltocsv.processor;
import com.walking.techie.xmltocsv.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.csv100,Walking Techie,CS 101,John Doe,CS 102,Sachin Tendulkar,CS
output in console
2017-03-26 18:04:42.769 INFO 4272 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=CsvToXmlJob]] launched with the following parameters: [{}]
2017-03-26 18:04:42.786 INFO 4272 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [step1]
2017-03-26 18:04:42.873 INFO 4272 --- [ main] c.w.t.x.processor.StudentProcessor : Student processed : Student(rollNo=100, name=Walking Techie, department=CS)
2017-03-26 18:04:42.874 INFO 4272 --- [ main] c.w.t.x.processor.StudentProcessor : Student processed : Student(rollNo=101, name=John Doe, department=CS)
2017-03-26 18:04:42.874 INFO 4272 --- [ main] c.w.t.x.processor.StudentProcessor : Student processed : Student(rollNo=102, name=Sachin Tendulkar, department=CS)
2017-03-26 18:04:42.887 INFO 4272 --- [ 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.
Hi,
ReplyDeleteThank for the nice work.I need the code for read the data from oracle database and write it to xls file using spring batch.
Thanks
Hi,
DeleteThank you for visiting this blog. You can refer to the this example it can help you.
http://walkingtechie.blogspot.com/2017/03/spring-batch-mysql-to-xml-file.html
I suggest to do the all the example given in this list http://walkingtechie.blogspot.in/2017/03/spring-batch-with-spring-boot.html