Spring Boot + Spring Batch Job Parameters (2022) Hello World Example
In this tutorial we will be implementing how the job parameters can be passed at runtime with the help of an example.Spring Batch is one of the open-source framework available for batch processing.
A batch job is a combination of reading input, processing the data and finally presenting the processed data in the form of output. Job Parameters can be defined as the data that are provided for a job to get started. They are in the form of key-value pairs. Different instances of a job are differentiated on the basis of job parameters. To access the job parameter, Spring Expression Language can be used.
Table Of Contents :
The names are passed from xml file to csv file with the use of JobParameters to JobLauncher.
The flow between the application controller, the Job Launcher and the Job is described as follows:-
Here I would be passing the names of xml and csv files as job parameters.
-
This will be the standard directory layout for maven project structure-
We need to start by creating a Maven pom.xml(Project Object Model) file. The pom.xml file contains the project configuration details.<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>SpringBatchJobParam</groupId> <artifactId>SpringBatchJobParam</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.batch</groupId> <artifactId>spring-batch-core</artifactId> <version>3.0.7.RELEASE</version> </dependency> <!-- Spring XML to/back object --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>4.3.5.RELEASE</version> </dependency> </dependencies> </project>
Under src/main/resources, create a new folder xml and then create a xml file named AllPersonDetail.xml.<?xml version="1.0" encoding="UTF-8" ?> <Bank> <person personId="1"> <name>A</name> <balance>3334</balance> </person> <person personId="2"> <name>B</name> <balance>1099</balance> <dob>26/7/1983</dob> <income>100,999</income> </person> <person personId="3"> <name>Z</name> <balance>400</balance> </person> <person personId="4"> <name>B</name> <balance>900</balance> <dob>26/7/1983</dob> <income>100,999</income> </person> </Bank>
Creating the model class for smooth converting spring bean into to csvfile.
@XmlElement is used here for mapping with xml schema.An xml document can have multiple xml element.
@XmlAttribute is used here for defining properties in xml schema.
@XmlRootElement denotes the root element of the xml file.package com.codeusingjava.model; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name="person") public class Person { private int personId; private String name; private int balance; @XmlAttribute(name = "personId") public int getPersonId() { return personId; } public void setPersonId(int personId) { this.personId = personId; } @XmlElement(name = "name") public String getName() { return name; } public void setName(String name) { this.name = name; } @XmlElement(name = "balance") public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } }
Here the job parameters are defined in the form of key-value pairs and then passed to job launcher.package com.codeusingjava.main; 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.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApplication { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("config/personData.xml","config/appcontext.xml"); JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher"); Job job = (Job) context.getBean("totalPersonReport"); try { JobParametersBuilder jobBuilder= new JobParametersBuilder(); jobBuilder.addString("lowbalancepersons", "SelectedPersons"); jobBuilder.addString("alldetailsfileName","AllPersonDetail"); JobParameters jobParameters =jobBuilder.toJobParameters(); JobExecution execution = jobLauncher.run(job, jobParameters); System.out.println("Completion Status : " + execution.getStatus()); } catch (Exception e) { e.printStackTrace(); } System.out.println("Done"); } }
Creating the processor class.It filters the person having less balance then minimum value.
The processor class reads each and every data element, then processes the data and finally writes the processed record in the writer.package com.codeusingjava.processor; import org.springframework.batch.item.ItemProcessor; import com.codeusingjava.model.Person; public class SelectedPersonsReportProcessor implements ItemProcessor<Person, Person> { public Person process(Person item) throws Exception { if(item.getBalance() >1000){ return null; // null = ignore this object } return item; } }
Inside src/main/resources, create a new folder named config and create a class named appcontext.xml<beans xmlns="http://www.springframework.org/schema/beans" 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-3.2.xsd"> <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> <property name="transactionManager" ref="transactionManager" /> </bean> <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> </beans>
Create another class inside config folder named personData.xml<beans xmlns="http://www.springframework.org/schema/beans" xmlns:batch="http://www.springframework.org/schema/batch" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <batch:job id="totalPersonReport"> <batch:step id="step1"> <batch:tasklet> <batch:chunk reader="xmlItemReader" writer="cvsFileItemWriter" processor="selectedPersonsReportProcessor" commit-interval="1"> </batch:chunk> </batch:tasklet> </batch:step> </batch:job> <bean id="selectedPersonsReportProcessor" class="com.codeusingjava.processor.SelectedPersonsReportProcessor" scope="step"/> <bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader" scope="step"> <property name="fragmentRootElementName" value="person" /> <property name="resource" value="classpath:xml/#{jobParameters['alldetailsfileName']}.xml" /> <property name="unmarshaller" ref="reportUnmarshaller" /> </bean> <!-- Read and map values to object, via jaxb2 --> <bean id="reportUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound"> <list> <value>com.codeusingjava.model.Person</value> </list> </property> </bean> <bean id="cvsFileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step"> <!-- write to this csv file --> <property name="shouldDeleteIfExists" value="true" /> <property name="resource" value="file:csv/#{jobParameters['lowbalancepersons']}.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="personId,name,balance" /> </bean> </property> </bean> </property> </bean> </beans>
To see the xml processed records into a csv file , see the csv file created as SelectedPersons.csv in the csv folder