Spring Batch Example in Spring boot - CSV File to XML File - Walking Techie

Blog about Java programming, Design Pattern, and Data Structure.

Tuesday, March 28, 2017

Spring Batch Example in Spring boot - CSV File to XML File

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.

2 comments :