dineshonjava

Spring Application Context Provider

Accessing the application context in java class is very easy. if you want to access the application context beans in any java class we have to set the application context at the time of server loading for that follow the following process

The following class is used to set values in the application context dynamically.

AppContext.java

package com.doj.spring;

import org.springframework.context.ApplicationContext;

/**
 * @author Dinesh
 *
 */

public class AppContext {

    private static ApplicationContext ctx;

    /**
     * Injected from the class "ApplicationContextProvider" which is automatically loaded during Spring-Initialization.
     */
    public static void setApplicationContext(ApplicationContext applicationContext) {
        ctx = applicationContext;
    }

    /**
     * Get access to the Spring ApplicationContext from everywhere in your Application.
     * 
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return ctx;
    }

}


The following class is used to set the application context at the time of loading the server.


ApplicationContextProvider.java

package com.doj.spring;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.doj.spring.AppContext;

/**
 * @author Dinesh
 *
 */
public class ApplicationContextProvider implements ApplicationContextAware {

    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        // Wiring the ApplicationContext into a static method
        AppContext.setApplicationContext(ctx);
    }
}


Place the following line in applicationContext.xml file

applicationContext.xml

<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<!-- Application Context Provider -->
 <bean id="contextApplicationContextProvider" class="com.doj.spring.ApplicationContextProvider"></bean>



Spring Application Context provider, in any java class, provide Application context, dynamically.
Spring Related Topics you may like
  1. Spring Interview Questions and Answers
  2. Spring AOP Interview Questions and Answers
  3. Spring MVC Interview Questions
  4. Spring Security Interview Questions and Answers
  5. Spring REST Interview Questions and Answers
  6. Spring Boot Interview Questions and Answers
  7. Spring Boot Microservices Interview Questions and Answers
  8. Dependency Injection (DI) in Spring
  9. Spring IoC Container
  10. What is Bean Factory in Spring
  11. ApplicationContext in Spring
  12. Bean Autowiring in Spring
  13. Spring Bean Scopes
  14. Create Custom Bean Scope in Spring Example
  15. Using ApplicationContextAware in Spring
  16. Spring Bean Life Cycle and Callbacks
  17. BeanPostProcessor in Spring
  18. BeanFactoryPostProcessor in Spring
  19. Annotations in Spring and Based Configuration
  20. Spring JSR-250 Annotations
  21. JSR 330 Annotations in Spring
  22. Spring @Component, @Repository, @Service and @Controller Stereotype Annotations
  23. Method injection with Spring using Lookup method property
  24. Spring AOP-Introduction to Aspect Oriented Programming
  25. @Aspect Annotation in Spring
  26. Spring AOP AspectJ @Before Annotation Advice Example
  27. Spring AOP Before Advice Example using XML Config
  28. Spring AOP AspectJ @After Annotation Advice Example
  29. Spring AOP After Advice Example using XML Config
  30. Spring AOP AspectJ @AfterReturning Annotation Advice Example
  31. Spring AOP After-Returning Advice Example using XML Config
  32. Spring AOP AspectJ @AfterThrowing Annotation Advice Example
  33. Spring AOP After Throwing Advice Example using XML Config
  34. Spring AOP AspectJ @Around Annotation Advice Example
  35. Spring AOP Around Advice Example using XML Config
  36. Spring AOP Proxies in Spring
  37. Spring AOP Transaction Management in Hibernate
  38. Spring Transaction Management
  39. Spring Declarative Transaction Management Example
  40. Spring AOP-Ordering of Aspects with Example
  41. Spring Security Java Based Configuration with Example
  42. Spring Security XML Namespace Configuration Example

Spring Application Context Provider


Spring Batch TaskScheduler Example

Why do we need scheduling?
Scheduling is needed if you want to automate the repetition of a task at specific intervals or particular date. You could of course manually watch the time and execute your task, albeit an inefficient task. Who wants to watch the computer every 10 seconds just to hit the Enter key? No one.


In this example we use a simple configuration and an example implementation of ItemReader and ItemWriter, as you can see below. The Job is defined to run every 10 seconds. While everything works well in the first iteration, reading and writing seems to be skipped in the subsequent iterations.
<batch:job id="simpleDojJob" parent="simpleJob">
     <batch:step id="step1">
      <batch:tasklet>
       <batch:chunk reader="xmlItemReader" writer="mongodbItemWriter" commit-interval="2" processor="employeeFilter"/>
      </batch:tasklet>
     </batch:step>
    </batch:job>   
<bean id="runScheduler" class="com.doj.batch.scheduler.RunScheduler" />
 
  <!-- Run every 10 seconds -->
   <task:scheduled-tasks>
  <task:scheduled ref="runScheduler" method="run" cron="*/10 * * * * *" />
   </task:scheduled-tasks>
In this tutorial, we will show you how to use Spring TaskScheduler to schedule a batch job to run every 5 seconds.

Tools and libraries used
  • Spring Tool Suite (STS)
  • JDK 1.6
  • Spring Core 3.2.2.RELEASE
  • Spring OXM 3.2.2.RELEASE
  • Spring Batch 2.2.0.RELEASE
  • MongoDB Java Driver 2.7.3
  • MongoDB 2.10.1

1. Project Directory Structure
Spring Batch TaskScheduler Example

2. Spring TaskScheduler
Spring 3.0 introduces a TaskScheduler for scheduling tasks. It is part of the Spring-Core, no need to declare an extra dependency. A scheduler triggers launch Spring Batch jobs, by accessing the Spring Batch runtime.

<!-- Run every 10 seconds -->
   <task:scheduled-tasks>
  <task:scheduled ref="runScheduler" method="run" cron="*/10 * * * * *" />
   </task:scheduled-tasks>
  <task:scheduled-tasks>
  <task:scheduled ref="runScheduler" method="run" fixed-delay="10000" />
   </task:scheduled-tasks>

The TaskScheduler will schedule to run below bean.
package com.doj.batch.scheduler;

import java.util.Date;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author Dinesh Rajput
 *
 */
@Component
public class RunScheduler {
 @Autowired
 private JobLauncher jobLauncher;
  
 @Autowired
 private Job job;
 
 public void run() {
     try {
   String dateParam = new Date().toString();
   JobParameters param = new JobParametersBuilder().addString("date", dateParam).toJobParameters();
   System.out.println(dateParam);
   JobExecution execution = jobLauncher.run(job, param);
   System.out.println("Exit Status : " + execution.getStatus());
     } catch (Exception e) {
      //e.printStackTrace();
     }
   }
}

Input XML File
employees.xml
s<?xml version="1.0" encoding="UTF-8"?>
<employees>
 <employee>
  <address>delhi</address>
  <age>37</age>
  <empid>1111</empid>
  <name>ATUL KUMAR</name>
  <salary>300000.0</salary>
 </employee>
 <employee>
  <address>delhi</address>
  <age>27</age>
  <empid>2222</empid>
  <name>Dinesh Rajput</name>
  <salary>60000.0</salary>
 </employee>
 <employee>
  <address>delhi</address>
  <age>31</age>
  <empid>3333</empid>
  <name>ASHUTOSH RAJPUT</name>
  <salary>400000.0</salary>
 </employee>
 <employee>
  <address>Kanpur</address>
  <age>27</age>
  <empid>4444</empid>
  <name>Adesh Verma</name>
  <salary>80000.0</salary>
 </employee>
 <employee>
  <address>Noida</address>
  <age>37</age>
  <empid>5555</empid>
  <name>Dinesh Rajput</name>
  <salary>300000.0</salary>
 </employee>
</employees>

Employee.java
package com.doj.batch.bean;

import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author Dinesh Rajput
 *
 */
@XmlRootElement(name="employee")
public class Employee {
 private int empid;
 private String name;
 private int age;
 private float salary;
 private String address;
 /**
  * @return the empid
  */
 public int getEmpid() {
  return empid;
 }
 /**
  * @param empid the empid to set
  */
 public void setEmpid(int empid) {
  this.empid = empid;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the age
  */
 public int getAge() {
  return age;
 }
 /**
  * @param age the age to set
  */
 public void setAge(int age) {
  this.age = age;
 }
 /**
  * @return the salary
  */
 public float getSalary() {
  return salary;
 }
 /**
  * @param salary the salary to set
  */
 public void setSalary(float salary) {
  this.salary = salary;
 }
 /**
  * @return the address
  */
 public String getAddress() {
  return address;
 }
 /**
  * @param address the address to set
  */
 public void setAddress(String address) {
  this.address = address;
 }
 
 public String toString(){
  return "Name- "+name+" Age- "+age+" salary- "+salary+" address "+address;
 }
 
}

4. Job configuration
simple-job.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:task="http://www.springframework.org/schema/task"
 xmlns:batch="http://www.springframework.org/schema/batch"
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/batch 
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd">
 <context:component-scan base-package="com.doj.batch" />
 <import resource="applicationContext.xml"/>
 <import resource="mongodbConfig.xml"/>
 
 <bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
  <property name="resource" value="classpath:xml/employees.xml" />
  <property name="unmarshaller" ref="empUnMarshaller" />
  <property name="fragmentRootElementName" value="employee" />
   </bean>
 <bean id="empUnMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
  <property name="classesToBeBound">
   <value>com.doj.batch.bean.Employee</value>
  </property>
   </bean>
 <!-- write it to MongoDB, 'employee' collection (table) -->
    <bean id="mongodbItemWriter" class="org.springframework.batch.item.data.MongoItemWriter">
  <property name="template" ref="mongoTemplate" />
  <property name="collection" value="employee" />
    </bean>
    
    <bean id="employeeFilter" class="com.doj.batch.process.EmployeeFilter"></bean>
    
    <batch:job id="simpleDojJob" parent="simpleJob">
     <batch:step id="step1">
      <batch:tasklet>
       <batch:chunk reader="xmlItemReader" writer="mongodbItemWriter" commit-interval="2" processor="employeeFilter"/>
      </batch:tasklet>
     </batch:step>
    </batch:job>   
    
    <bean id="runScheduler" class="com.doj.batch.scheduler.RunScheduler" />
 
  <!-- Run every 10 seconds -->
   <task:scheduled-tasks>
  <task:scheduled ref="runScheduler" method="run" cron="*/10 * * * * *" />
   </task:scheduled-tasks>
</beans>

Run It-
Loads the Spring application context, the scheduler will be run automatically.
TestBatch.java
package com.doj.batch.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author Dinesh Rajput
 *
 */
public class TestBatch {

 /**
  * @param args
  */
 public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext("simple-job.xml");
 }

}

Output, it insert the xml content every 10 seconds in mongodb.

............
..............
Mar 9, 2014 5:43:18 PM org.springframework.oxm.jaxb.Jaxb2Marshaller createJaxbContextFromClasses
INFO: Creating JAXBContext with classes to be bound [class com.doj.batch.bean.Employee]
Sun Mar 09 17:43:20 IST 2014
Mar 9, 2014 5:43:20 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run
INFO: Job: [FlowJob: [name=simpleDojJob]] launched with the following parameters: [{date=Sun Mar 09 17:43:20 IST 2014}]
Mar 9, 2014 5:43:20 PM org.springframework.batch.core.job.AbstractJob handleStep
INFO: Executing step: [TaskletStep: [name=step1]]
Name- ATUL KUMAR Age- 37 salary- 300000.0 address delhi
Mar 9, 2014 5:43:20 PM org.springframework.oxm.jaxb.Jaxb2Marshaller processSource
Name- ASHUTOSH RAJPUT Age- 31 salary- 400000.0 address delhi
Mar 9, 2014 5:43:20 PM org.springframework.oxm.jaxb.Jaxb2Marshaller processSource
Name- Dinesh Rajput Age- 37 salary- 300000.0 address Noida
Exit Status : COMPLETED
Mar 9, 2014 5:43:20 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run
INFO: Job: [FlowJob: [name=simpleDojJob]] completed with the following parameters: [{date=Sun Mar 09 17:43:20 IST 2014}] and the following status: [COMPLETED]
Sun Mar 09 17:43:30 IST 2014
......................
...........................

TaskScheduler Example


Download Source Code with Jars
SpringBatchTaskSchedulerExample.zip




MultiResourceItemReader in Spring Batch Example

Class MultiResourceItemReader
Reads items from multiple resources sequentially - resource list is given by setResources(Resource[]), the actual reading is delegated to setDelegate(ResourceAwareItemReaderItemStream). Input resources are ordered using setComparator(Comparator) to make sure resource ordering is preserved between job runs in restart scenario.

MultiResourceItemReader class reads items from multiple resources sequentially.

Suppose one of the question in mind of user-

 
I have a Spring batch operation where I have sources file1, file2 and file3 to read from, and want to write to fileA, fileB and fileC like the following:

file1->fileA
file2->fileB
file3->fileC


In some scenario use want to put these three resources into a single file. In this example, we will show you how to read items from multiple resources (multiple xml files), and write the items into a single xml file.

emp-111.xml + emp-222.xml + emp-333.xml = employees.xml
Tools and libraries used

  • Spring Tool Suite (STS)
  • JDK 1.6
  • Spring Core 3.2.2.RELEASE
  • Spring OXM 3.2.2.RELEASE
  • Spring Batch 2.2.0.RELEASE
1. Project Directory Structure
MultiResourceItemReader in Spring Batch Example

2. Input XML Files
There are 3 xml files, later we will use MultiResourceItemReader to read it one by one.

emp-111.xml
<?xml version="1.0" encoding="UTF-8"?>
<employees>
 <employee>
  <address>Mumbai</address>
  <age>17</age>
  <empid>111</empid>
  <name>ATUL KUMAR</name>
  <salary>700000.0</salary>
 </employee>
</employees>

emp-222.xml
<?xml version="1.0" encoding="UTF-8"?>
<employees>
 <employee>
  <address>Noida</address>
  <age>21</age>
  <empid>222</empid>
  <name>ASHUTOSH RAJPUT</name>
  <salary>400000.0</salary>
 </employee>
</employees>

emp-333.xml
<?xml version="1.0" encoding="UTF-8"?>
<employees>
 <employee>
  <address>Delhi</address>
  <age>17</age>
  <empid>333</empid>
  <name>Dinesh Rajput</name>
  <salary>300000.0</salary>
 </employee>
</employees>

3. ItemReader for XML File
In this example, we use Jaxb2Marshaller to map XML values and attributes to an object.
<bean class="org.springframework.batch.item.xml.StaxEventItemReader" id="xmlItemReader">
   <property name="unmarshaller" ref="empUnMarshaller">
  <property name="fragmentRootElementName" value="employee">
 </property></property></bean>

Employee.java
package com.doj.batch.bean;

import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author Dinesh Rajput
 *
 */
@XmlRootElement(name="employee")
@XmlAccessorOrder(XmlAccessOrder.UNDEFINED)
public class Employee {
 private int empid;
 private String name;
 private int age;
 private float salary;
 private String address;
 /**
  * @return the empid
  */
 public int getEmpid() {
  return empid;
 }
 /**
  * @param empid the empid to set
  */
 public void setEmpid(int empid) {
  this.empid = empid;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the age
  */
 public int getAge() {
  return age;
 }
 /**
  * @param age the age to set
  */
 public void setAge(int age) {
  this.age = age;
 }
 /**
  * @return the salary
  */
 public float getSalary() {
  return salary;
 }
 /**
  * @param salary the salary to set
  */
 public void setSalary(float salary) {
  this.salary = salary;
 }
 /**
  * @return the address
  */
 public String getAddress() {
  return address;
 }
 /**
  * @param address the address to set
  */
 public void setAddress(String address) {
  this.address = address;
 }
 
}
4. Spring Batch Core configuration
Define jobRepository and jobLauncher.
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

 <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
 
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository"/>
    </bean>
 
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
 
    <bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob" abstract="true">
        <property name="jobRepository" ref="jobRepository" />
    </bean>
 
</beans>

5. Spring Batch Jobs Configuration
simple-job.xml
A job to read resources that matches this pattern xml/inputs/emp-*.xml, and write it into a single xml file employees.xml.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:batch="http://www.springframework.org/schema/batch"
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/batch 
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd">

 <import resource="applicationContext.xml"/>
 
 <bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
  <property name="unmarshaller" ref="empUnMarshaller" />
  <property name="fragmentRootElementName" value="employee" />
   </bean>
   
 <bean id="empUnMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
  <property name="classesToBeBound">
   <value>com.doj.batch.bean.Employee</value>
  </property>
   </bean>
   
   <bean id="multiResourceReader" class=" org.springframework.batch.item.file.MultiResourceItemReader">
  <property name="resources" value="file:xml/inputs/emp-*.xml" />
  <property name="delegate" ref="xmlItemReader" />
  </bean>
  
 <bean id="xmlItemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
  <property name="resource" value="file:xml/outputs/employees.xml" />
  <property name="marshaller" ref="empMarshaller" />
  <property name="rootTagName" value="employees" />
  </bean> 
  
  <bean id="empMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
  <property name="classesToBeBound">
   <value>com.doj.batch.bean.Employee</value>
  </property>
   </bean> 
    
    <batch:job id="simpleDojJob" parent="simpleJob">
     <batch:step id="step1">
      <batch:tasklet>
       <batch:chunk reader="multiResourceReader" writer="xmlItemWriter" commit-interval="1"/>
      </batch:tasklet>
     </batch:step>
    </batch:job>   
</beans>

6. Launching Batch Job-
Spring Batch comes with a simple utility class called CommandLineJobRunner which has a main() method which accepts two arguments. First argument is the spring application context file containing job definition and the second is the name of the job to be executed.

Now run as a java application with both two arguments.
org.springframework.batch.core.launch.support.CommandLineJobRunner
simple-job.xml simpleDojJob

Output. The Spring Batch are created the content of employees.xml.
<?xml version="1.0" encoding="UTF-8"?>
<employees>
 <employee>
  <address>Mumbai</address>
  <age>17</age>
  <empid>111</empid>
  <name>ATUL KUMAR</name>
  <salary>700000.0</salary>
 </employee>
 <employee>
  <address>Noida</address>
  <age>21</age>
  <empid>222</empid>
  <name>ASHUTOSH RAJPUT</name>
  <salary>400000.0</salary>
 </employee>
 <employee>
  <address>Delhi</address>
  <age>17</age>
  <empid>333</empid>
  <name>Dinesh Rajput</name>
  <salary>300000.0</salary>
 </employee>
</employees>


Download Source Code with Jars
SpringBatchMultiResource.zip









Spring Batch Example XML to MongoDB

Spring Batch and MongoDB-
In Spring Batch 2.2.0 version introduce NoSQL database support with introducing org.springframework.batch.item.data package which contain following classes.
  • AbstractPaginatedDataItemReader.class
  • GemfireItemWriter.class
  • MongoItemReader.class
  • MongoItemWriter.class
  • Neo4jItemReader.class
  • Neo4jItemWriter.class
  • RepositoryItemReader.class
  • RepositoryItemWriter.class
  • SpELMappingGemfireItemWriter.class

Spring Batch 2.2.0
Spring Batch is a Spring-based framework for enterprise Java batch processing. An important aspect of Spring Batch is the separation between reading from and writing to resources and the processing of a single record, called item in the Spring Batch lingo. There are a lot of existing item readers and writers for a wide range of resources like JDBC databases, JMS messaging systems, flat file etc. If the resource of your choice is not supported of of the box, it is easy to implement your own reader and writer as we will see in a minute.

MongoDB
MongoDB is a popular NoSQL datastore. It stores so called documents (basically an ordered set of key/value pairs where a value can be a simple data type like String or integer but also an array of values or a sub document). MongoDB is optimized for heavy write throughput and horizontal scaling.

Since I am a big fan of MongoDB on the one hand and introducing the Spring Batch framework at one of my customers on the other hand, why not implement a Spring Batch item reader(xml reader) and writer for MongoDB(MongoItemWriter).

MongoDB Item Writer-MongoItemWriter
My first approach to the item writer was very naive. I just took the DBObject item list and inserted them into the target collection. This can be done with the following configuration:
<!-- write it to MongoDB, 'employee' collection (table) -->
    <bean id="mongodbItemWriter" class="org.springframework.batch.item.data.MongoItemWriter">
  <property name="template" ref="mongoTemplate" />
  <property name="collection" value="employee" />
    </bean>
These are possible parameters:
template and collection determine the MongoDB template and what collection to write to. These parameters are required, all other are optional.

MongoDB Item Reader-MongoItemReader
Implementing the item reader was straightforward. It was merely a matter of passing parameters to the underlying MongoDB driver API.
<!-- reader it from MongoDB, 'employee' collection (table) -->
    <bean id="mongodbItemReader" class="org.springframework.batch.item.data.MongoItemReader">
  <property name="template" ref="mongoTemplate" />
  <property name="query" value="{age: {$gt: 22}" />
    </bean>
We have three kinds of parameters:

template and collection determine the MongoDB template and what collection to read from. These parameters are required, all other are optional.
query and keys are making up the MongoDB query. The first one is the query itself, the second one selects the field to read. If you don’t set a query string, all documents from the collection are read.

By default, the item reader emits DBObject instances that come from the MongoDB driver API. These objects are basically ordered hashmaps. If you want to use another representation of your data in the item processor, you can write a custom converter.
public class DocumentEmployeeConverter implements Converter<DBObject Employee> {
 
 @Override
 public Employee convert(DBObject document) {
  Employee emp = new Employee();
   emp.setEmpid((String)document.get("_id"));
  emp.setName((String)document.get("name"));
  emp.setAge((Integer)document.get("age"));
                emp.setSalary((Integer)document.get("salary"));
                emp.setAddress((String)document.get("address"));
  return emp;
 }
}
Example XML File To MongoDB Database-
Now we will discuss how to configure a Spring Batch job to read data from an XML file (XStream library) into a no SQL database (MongoDB). In additional, create a unit test case to launch and test the batch jobs.

Tools and libraries used
  • Spring Tool Suite (STS)
  • JDK 1.6
  • Spring Core 3.2.2.RELEASE
  • Spring OXM 3.2.2.RELEASE
  • Spring Batch 2.2.0.RELEASE
  • MongoDB Java Driver 2.7.3
  • MongoDB 2.10.1

1. Project Directory Structure

Spring Batch Example XML to MongoDB

2. Input XML File
employees.xml
<?xml version="1.0" encoding="UTF-8"?>
<employees>
 <employee>
  <address>delhi</address>
  <age>17</age>
  <empid>1111</empid>
  <name>ATUL KUMAR</name>
  <salary>300000.0</salary>
 </employee>
 <employee>
  <address>delhi</address>
  <age>27</age>
  <empid>2222</empid>
  <name>Dinesh Rajput</name>
  <salary>60000.0</salary>
 </employee>
 <employee>
  <address>delhi</address>
  <age>21</age>
  <empid>3333</empid>
  <name>ASHUTOSH RAJPUT</name>
  <salary>400000.0</salary>
 </employee>
 <employee>
  <address>Kanpur</address>
  <age>27</age>
  <empid>4444</empid>
  <name>Adesh Verma</name>
  <salary>80000.0</salary>
 </employee>
 <employee>
  <address>Noida</address>
  <age>37</age>
  <empid>5555</empid>
  <name>Dinesh Rajput</name>
  <salary>300000.0</salary>
 </employee>
</employees>

3. ItemReader for XML File
In this example, we use Jaxb2Marshaller to map XML values and attributes to an object.
<bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
  <property name="resource" value="classpath:xml/employees.xml" />
  <property name="unmarshaller" ref="empUnMarshaller" />
  <property name="fragmentRootElementName" value="employee" />
   </bean>

Employee.java
package com.doj.batch.bean;

import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author Dinesh Rajput
 *
 */
@XmlRootElement(name="employee")
@XmlAccessorOrder(XmlAccessOrder.UNDEFINED)
public class Employee {
 private int empid;
 private String name;
 private int age;
 private float salary;
 private String address;
 /**
  * @return the empid
  */
 public int getEmpid() {
  return empid;
 }
 /**
  * @param empid the empid to set
  */
 public void setEmpid(int empid) {
  this.empid = empid;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the age
  */
 public int getAge() {
  return age;
 }
 /**
  * @param age the age to set
  */
 public void setAge(int age) {
  this.age = age;
 }
 /**
  * @return the salary
  */
 public float getSalary() {
  return salary;
 }
 /**
  * @param salary the salary to set
  */
 public void setSalary(float salary) {
  this.salary = salary;
 }
 /**
  * @return the address
  */
 public String getAddress() {
  return address;
 }
 /**
  * @param address the address to set
  */
 public void setAddress(String address) {
  this.address = address;
 }
 
}
4. MongoDB configuration
mongodbConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:mongo="http://www.springframework.org/schema/data/mongo"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  http://www.springframework.org/schema/data/mongo
        http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd">
 
    <mongo:mongo host="127.0.0.1" port="27017" />
 <mongo:db-factory dbname="davdb" id="mongoDbFactory"/>
 
 <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
  <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
 </bean>
 
</beans>

5. Spring Batch Core configuration
Define jobRepository and jobLauncher.
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

 <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
 
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository"/>
    </bean>
 
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
 
    <bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob" abstract="true">
        <property name="jobRepository" ref="jobRepository" />
    </bean>
 
</beans>

6. Spring Batch Jobs Configuration file
First, I define the simple-job.xml and mongodbConfig.xml files for configuration. In these file, I specify the org.springframework.batch.item.xml.StaxEventItemReader, which is a class from the Spring Batch framework. I specify the resource to the org.springframework.batch.item.xml.StaxEventItemReader as the path of the input xml file. Here I say the resource value is classpath:xml\employees.xml, i.e., the location of input file employees.xml. I also define the unmarshaller object for converting xml data to java object of Employee class. Then I define fragmentRootElementName, which have value employee . I can cater that through my defined EmployeeFilterProcessor class which implements the ItemProcessor class of the Spring Batch framework.

After this, I specify the MongoDB details by mentioning the hostname where the database is installed and also the port number. I access the database through the MongoTemplate, which takes the reference of the database details mentioned through the id (i.e., Mongo as the argument). In the MongoTemplate I also pass the other argument (i.e., the name of the database I will work with inside the MongoDB), and in this case it is "new." Now I define my own class, MongoDBItemWriter, which is the extension of the ItemWriter class in Spring Batch. This class now reads the MongoTemplate to get the details of the database.

Next, I specify the DynamicJobParameters class, which implements the JobParametersIncrementer from the Spring Batch. This works as the incrementer for the job.

Finally, I specify my batch job where I give the batch:step and batch:tasklet details. The batch job here is simpleDojJob, which contains a single step that holds the tasklet where the task mentioned is to read the batch:chunk from the xmlItemReader. I also mention the process and the itemwriter details.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:batch="http://www.springframework.org/schema/batch"
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/batch 
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd">

 <import resource="applicationContext.xml"/>
 <import resource="mongodbConfig.xml"/>
 <bean id="employeeFilterProcessor" class="com.doj.batch.processor.EmployeeFilterProcessor">
 <bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
  <property name="resource" value="classpath:xml/employees.xml" />
  <property name="unmarshaller" ref="empUnMarshaller" />
  <property name="fragmentRootElementName" value="employee" />
   </bean>
 <bean id="empUnMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
  <property name="classesToBeBound">
   <value>com.doj.batch.bean.Employee</value>
  </property>
   </bean>
 <!-- write it to MongoDB, 'employee' collection (table) -->
    <bean id="mongodbItemWriter" class="org.springframework.batch.item.data.MongoItemWriter">
  <property name="template" ref="mongoTemplate" />
  <property name="collection" value="employee" />
    </bean>
    
    <batch:job id="simpleDojJob" parent="simpleJob">
     <batch:step id="step1">
      <batch:tasklet>
       <batch:chunk reader="xmlItemReader" processor="employeeFilterProcessor" writer="mongodbItemWriter" commit-interval="2"/>
      </batch:tasklet>
     </batch:step>
    </batch:job>   
</beans>

8. EmployeeFilterProcessor.java
package com.doj.batch.processor;

import org.springframework.batch.item.ItemProcessor;

import com.doj.batch.bean.Employee;

/**
 * @author Dinesh Rajput
 *
 */
public class EmployeeFilterProcessor implements ItemProcessor<Employee, Employee> {

 @Override
 public Employee process(Employee emp) throws Exception {
  if(emp.getSalary() > 70000.0){
   return emp;
  }else{
   return null;
  }
 }
}

Launching Batch Job-
Spring Batch comes with a simple utility class called CommandLineJobRunner which has a main() method which accepts two arguments. First argument is the spring application context file containing job definition and the second is the name of the job to be executed.

Now run as a java application with both two arguments.
org.springframework.batch.core.launch.support.CommandLineJobRunner
simple-job.xml simpleDojJob

Output. The Spring Batch metadata tables are created, and the content of employees.xml is inserted into mongodb database "davdb" collection "EMPLOYEE".

Spring Batch Example XML to MongoDB



Download Source Code with Jars
SpringBatchXMLtoMongoDB.zip










Spring Batch Example CSV file to MySQL Database

In this tutorial, we will discuss about an application where we see how to configure a Spring Batch job to read CSV file by FlatFileReader library write into a MySQL database, and also we can filter out some of the records of employees which have less salary or under age employee before writing with ItemProcessor.

Tools and libraries used
  • Spring Tool Suite (STS)
  • JDK 1.6
  • Spring Core 3.2.2.RELEASE
  • Spring OXM 3.2.2.RELEASE
  • Spring Batch 2.2.0.RELEASE
  • MySQL Java Driver 5.1.25

Sample Example of Spring Batch CSV To MySQL Database-
1. Project Directory Structure
Spring Batch CSV file to MySQL Database Application
2. Input CSV File
employees.csv

1111,ATUL KUMAR,17,300000.0,delhi
3333,ASHUTOSH RAJPUT,21,400000.0,delhi
4444,Adesh Verma,27,80000.0,Kanpur
5555,Dinesh Rajput,37,300000.0,Noida
2222,ATUL KUMAR,17,300000.0,delhi
6666,ASHUTOSH RAJPUT,21,400000.0,delhi
7777,Adesh Verma,27,80000.0,Kanpur
8888,Dinesh Rajput,37,300000.0,Noida

3. ItemReader for CSV Flat File reader
<bean id="employee" class="com.doj.batch.bean.Employee" scope="prototype"></bean>
 
 <bean id="cvsItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
  <!-- Read a csv file -->
  <property name="resource" value="classpath:csv/employees.csv" />
  <property name="lineMapper">
   <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
     <!-- split it -->
     <property name="lineTokenizer">
         <bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
       <property name="names" value="empid,name,age,salary,address" />
     </bean>
     </property>
     <property name="fieldSetMapper">   
      <!-- map to an object -->
      <bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
     <property name="prototypeBeanName" value="employee" />
      </bean>   
     </property>
     </bean>
    </property>
     </bean>
  
Employee.java
package com.doj.batch.bean;


/**
 * @author Dinesh Rajput
 *
 */
public class Employee {
 private int empid;
 private String name;
 private int age;
 private float salary;
 private String address;
 /**
  * @return the empid
  */
 public int getEmpid() {
  return empid;
 }
 /**
  * @param empid the empid to set
  */
 public void setEmpid(int empid) {
  this.empid = empid;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the age
  */
 public int getAge() {
  return age;
 }
 /**
  * @param age the age to set
  */
 public void setAge(int age) {
  this.age = age;
 }
 /**
  * @return the salary
  */
 public float getSalary() {
  return salary;
 }
 /**
  * @param salary the salary to set
  */
 public void setSalary(float salary) {
  this.salary = salary;
 }
 /**
  * @return the address
  */
 public String getAddress() {
  return address;
 }
 /**
  * @param address the address to set
  */
 public void setAddress(String address) {
  this.address = address;
 }
 
}

4. Database configuration
ApplicationDB.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  http://www.springframework.org/schema/jdbc 
  http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd">
 
        <!-- connect to database -->
 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://localhost:3306/DAVDB" />
  <property name="username" value="root" />
  <property name="password" value="root" />
 </bean>
 
 <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
 
</beans>

5. Spring Batch Core configuration
Define jobRepository and jobLauncher.
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

 <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
 
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository"/>
    </bean>
 
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
 
    <bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob" abstract="true">
        <property name="jobRepository" ref="jobRepository" />
    </bean>
 
</beans>

6. Spring Batch Jobs Confifuration file
simple-job.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:batch="http://www.springframework.org/schema/batch"
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/batch 
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd">

 <import resource="applicationContext.xml"/>
 <import resource="ApplicationDB.xml"/>
 
 <bean id="employee" class="com.doj.batch.bean.Employee" scope="prototype"></bean>
 
 <bean id="cvsItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
  <!-- Read a csv file -->
  <property name="resource" value="classpath:csv/employees.csv" />
  <property name="lineMapper">
   <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
     <!-- split it -->
     <property name="lineTokenizer">
         <bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
       <property name="names" value="empid,name,age,salary,address" />
     </bean>
     </property>
     <property name="fieldSetMapper">   
      <!-- map to an object -->
      <bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
     <property name="prototypeBeanName" value="employee" />
      </bean>   
     </property>
     </bean>
    </property>
     </bean>
  
  <bean id="databaseItemWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
  <property name="dataSource" ref="dataSource" />
  <property name="sql">
    <value>
            <![CDATA[        
              insert into EMPLOYEET(empname,empAge,salary,empaddress) values (:name,:age,:salary,:address)
             ]]>
    </value>
  </property>
  <!-- It will take care matching between object property and sql name parameter -->
  <property name="itemSqlParameterSourceProvider">
   <bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
  </property>
    </bean>
    
    <batch:job id="simpleDojJob" job-repository="jobRepository" parent="simpleJob">
     <batch:step id="step1">
      <batch:tasklet transaction-manager="transactionManager">
       <batch:chunk reader="cvsItemReader" writer="databaseItemWriter" commit-interval="2"/>
      </batch:tasklet>
     </batch:step>
    </batch:job>   
</beans>

This is the main xml file to configure the Spring batch job. This simple-job.xml file define a job to read a employees.csv file, match it to employee plain pojo and write the data into MySQL database Employeet table.

7. Spring Batch ItemProcessor for filter data
In Spring batch, the wired Processor will be fired before writing to any resources, so, this is the best place to handle any conversion, filtering and business logic. In this example, we will be ignored all employees whose have salaried less than 70000 i.e. not write to database as well as ignored those employee whose age less than 22 years.

DataFilterProcessor.java
package com.doj.batch.processor;

import org.springframework.batch.item.ItemProcessor;

import com.doj.batch.bean.Employee;

/**
 * @author Dinesh Rajput
 *
 */
public class DataFilterProcessor implements ItemProcessor<Employee, Employee> {

 @Override
 public Employee process(Employee emp) throws Exception {
  if(emp.getSalary() > 70000.0 && emp.getAge() > 22){
   return emp;
  }else{
   return null;
  }
 }

}

8. Launching Batch Job-
Spring Batch comes with a simple utility class called CommandLineJobRunner which has a main() method which accepts two arguments. First argument is the spring application context file containing job definition and the second is the name of the job to be executed.

Now run as a java application with both two arguments.
org.springframework.batch.core.launch.support.CommandLineJobRunner
simple-job.xml simpleDojJob

Output. The Spring Batch metadata tables are created, and the content of employees.cvs is inserted into database table "EMPLOYEET".

Spring Batch Example CSV file to MySQL Database



Download Source Code with Jars
SpringBatchCSVtoDatabase.zip









Spring Batch Example XML To CSV File

In this tutorial, we will discuss about an application where we see how to configure a Spring Batch job to read XML file by JAXB2 library into a csv file, and filter out the record before writing with ItemProcessor.

Tools and libraries used
  • Spring Tool Suite (STS)
  • DK 1.6
  • Spring Core 3.2.2.RELEASE
  • Spring OXM 3.2.2.RELEASE
  • Spring Batch 2.2.0.RELEASE

Sample Example of Spring Batch XML To CSV-
1. Project Directory Structure
Spring Batch Example XML To CSV File

2. Input XML File
employees.xml
<?xml version="1.0" encoding="UTF-8"?>
<employees>
 <employee>
  <address>delhi</address>
  <age>17</age>
  <empid>1111</empid>
  <name>ATUL KUMAR</name>
  <salary>300000.0</salary>
 </employee>
 <employee>
  <address>delhi</address>
  <age>27</age>
  <empid>2222</empid>
  <name>Dinesh Rajput</name>
  <salary>60000.0</salary>
 </employee>
 <employee>
  <address>delhi</address>
  <age>21</age>
  <empid>3333</empid>
  <name>ASHUTOSH RAJPUT</name>
  <salary>400000.0</salary>
 </employee>
 <employee>
  <address>Kanpur</address>
  <age>27</age>
  <empid>4444</empid>
  <name>Adesh Verma</name>
  <salary>80000.0</salary>
 </employee>
 <employee>
  <address>Noida</address>
  <age>37</age>
  <empid>5555</empid>
  <name>Dinesh Rajput</name>
  <salary>300000.0</salary>
 </employee>
</employees>

3. ItemReader for XML File
In this example, we use Jaxb2Marshaller to map XML values and attributes to an object.
<bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
  <property name="resource" value="classpath:xml/employees.xml" />
  <property name="unmarshaller" ref="empUnMarshaller" />
  <property name="fragmentRootElementName" value="employee" />
   </bean>

Employee.java
package com.doj.batch.bean;

import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author Dinesh Rajput
 *
 */
@XmlRootElement(name="employee")
@XmlAccessorOrder(XmlAccessOrder.UNDEFINED)
public class Employee {
 private int empid;
 private String name;
 private int age;
 private float salary;
 private String address;
 /**
  * @return the empid
  */
 public int getEmpid() {
  return empid;
 }
 /**
  * @param empid the empid to set
  */
 public void setEmpid(int empid) {
  this.empid = empid;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the age
  */
 public int getAge() {
  return age;
 }
 /**
  * @param age the age to set
  */
 public void setAge(int age) {
  this.age = age;
 }
 /**
  * @return the salary
  */
 public float getSalary() {
  return salary;
 }
 /**
  * @param salary the salary to set
  */
 public void setSalary(float salary) {
  this.salary = salary;
 }
 /**
  * @return the address
  */
 public String getAddress() {
  return address;
 }
 /**
  * @param address the address to set
  */
 public void setAddress(String address) {
  this.address = address;
 }
 
}

In JAXB2, for complex data type like Date , will not map to the field automatically, even it’s annotated.

for this to make JAXB2 supports Date conversion, you need to create a custom Adapter to handle the Date format manually, then attaches the adapter via @XmlJavaTypeAdapter. Lets see how to map.
package com.doj.batch.adapter;

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.bind.annotation.adapters.XmlAdapter;

/**
 * @author Dinesh Rajput
 *
 */
public class DataJaxbAdapter extends XmlAdapter<String, Date>{
 
 private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
 
 @Override
 public Date unmarshal(String date) throws Exception {
  return dateFormat.parse(date);
 }

 @Override
 public String marshal(Date date) throws Exception {
  return dateFormat.format(date);
 }

}

@XmlRootElement(name="employee")
@XmlAccessorOrder(XmlAccessOrder.UNDEFINED)
public class Employee {
...
...
private Date doj;
...
@XmlJavaTypeAdapter(JaxbDateAdapter.class)
 @XmlElement
 public Date getDoj() {
  return doj;
 }
...
...

}

4. Spring Batch Core configuration

Define jobRepository and jobLauncher.
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

 <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
 
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository"/>
    </bean>
 
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
 
    <bean id="simpleJob" class="org.springframework.batch.core.job.SimpleJob" abstract="true">
        <property name="jobRepository" ref="jobRepository" />
    </bean>
 
</beans>

5. Spring Batch Jobs Confifuration file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:batch="http://www.springframework.org/schema/batch"
 xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/batch 
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd">

 <import resource="applicationContext.xml"/>
 
 <bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
  <property name="resource" value="classpath:xml/employees.xml" />
  <property name="unmarshaller" ref="empUnMarshaller" />
  <property name="fragmentRootElementName" value="employee" />
   </bean>
  
  <bean id="filterDataProcessor" class="com.doj.batch.processor.DataFilterProcessor" />
  
    <bean id="csvItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">
  <property name="shouldDeleteIfExists" value="true" />
  <property name="resource" value="file:csv/outputs/employees.csv" />
  <property name="lineAggregator">
     <bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
    <property name="delimiter" value="," />
    <property name="fieldExtractor">
       <bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
      <property name="names" value="empid, name, age, salary, address" />
        </bean>
         </property>
        </bean>
  </property>
  </bean> 
    
    <bean id="empUnMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
  <property name="classesToBeBound">
   <value>com.doj.batch.bean.Employee</value>
  </property>
   </bean> 
  
    <batch:job id="simpleDojJob" job-repository="jobRepository" parent="simpleJob">
     <batch:step id="step1">
      <batch:tasklet transaction-manager="transactionManager">
       <batch:chunk reader="xmlItemReader" processor="filterDataProcessor" writer="csvItemWriter" commit-interval="1"/>
      </batch:tasklet>
     </batch:step>
    </batch:job>   
</beans>

6. Spring Batch ItemProcessor for filter data
In Spring batch, the wired Processor will be fired before writing to any resources, so, this is the best place to handle any conversion, filtering and business logic. In this example, we will be ignored all employees whose have salaried less than 70000 i.e. not write to csv file.
DataFilterProcessor.java
package com.doj.batch.processor;

import org.springframework.batch.item.ItemProcessor;

import com.doj.batch.bean.Employee;

/**
 * @author Dinesh Rajput
 *
 */
public class DataFilterProcessor implements ItemProcessor<Employee, Employee> {

 @Override
 public Employee process(Employee emp) throws Exception {
  if(emp.getSalary() > 70000.0){
   return emp;
  }else{
   return null;
  }
 }

}


7. Launching Batch Job-
Spring Batch comes with a simple utility class called CommandLineJobRunner which has a main() method which accepts two arguments. First argument is the spring application context file containing job definition and the second is the name of the job to be executed.

Now run as a java application with both two arguments.
org.springframework.batch.core.launch.support.CommandLineJobRunner
simple-job.xml simpleDojJob

Output. Extracts all employees into an csv file from xml file.
employees.csv

1111,ATUL KUMAR,17,300000.0,delhi
3333,ASHUTOSH RAJPUT,21,400000.0,delhi
4444,Adesh Verma,27,80000.0,Kanpur
5555,Dinesh Rajput,37,300000.0,Noida



Download Source Code with libs
SpringBatchXMTtoCSV.zip