In this post I will explain how to add header and footer to the destination file created by Spring batch.
When Spring batch transfer records from source to destination file in batch, it provides facility through which the programmer can provide header and footer information that
has to added in the destination file.
To take advantage of that facility, we need to provide implementation to two interfaces which are FlatFileHeaderCallback and FlatFileFooterCallback.
Below is the implementation of the two interfaces
FlatFileHeaderCallback
package package3;
import java.io.IOException;
import java.io.Writer;
import org.springframework.batch.item.file.FlatFileHeaderCallback;
public class EmployeeHeaderCallback implements FlatFileHeaderCallback {
@Override
public void writeHeader(Writer writer) throws IOException {
writer.write("Header");
}
}
FlatFileFooterCallback
package package3;
import java.io.IOException;
import java.io.Writer;
import org.springframework.batch.item.file.FlatFileFooterCallback;
public class EmployeeFooterCallback implements FlatFileFooterCallback {
@Override
public void writeFooter(Writer writer) throws IOException {
writer.write("Footer");
}
}
As shown in the above code, we implement the two interfaces and provide implementation for “writeHeader” and “writeFooter” methods. In these methods we write “Header” text in the
header section and “Foooter” text in the footer section.
Next we create beans for the above classes and link to the writer bean as shown below
1 <bean id="headerCallback" class="package3.EmployeeHeaderCallback"/>
2 <bean id="footerCallback" class="package3.EmployeeFooterCallback"/>
3
4 <bean id="writer" class="org.springframework.batch.item.file.FlatFileItemWriter">
5 <property name="resource" value="file:DemoData2.txt"/>
6 <property name="lineAggregator">
7 <bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
8 <property name="fieldExtractor">
9 <bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
10 <property name="names" value="id,name,status,salary"/>
11 </bean>
12 </property>
13 </bean>
14 </property>
15 <property name="headerCallback" ref="headerCallback"/>
16 <property name="footerCallback" ref="footerCallback"/>
17 </bean>
At line 1 and 2 we define the beans. At 15 and 16 we set the property headerCallback and footerCallback of writer bean.
The complete configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:batch="http://www.springframework.org/schema/batch"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">
<bean id="employee" class="package3.Employee" scope="prototype"/>
<bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="file:DemoData1.txt"/>
<property name="linesToSkip" value="1"/>
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="id,name,status,salary"/>
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="employee"/>
</bean>
</property>
</bean>
</property>
</bean>
<bean id="headerCallback" class="package3.EmployeeHeaderCallback"/>
<bean id="footerCallback" class="package3.EmployeeFooterCallback"/>
<bean id="writer" class="org.springframework.batch.item.file.FlatFileItemWriter">
<property name="resource" value="file:DemoData2.txt"/>
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="fieldExtractor">
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="id,name,status,salary"/>
</bean>
</property>
</bean>
</property>
<property name="headerCallback" ref="headerCallback"/>
<property name="footerCallback" ref="footerCallback"/>
</bean>
<batch:job id="importProductsJob">
<batch:step id="readWriteProducts">
<batch:tasklet>
<batch:chunk reader="reader" writer="writer" commit-interval="50"/>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
</bean>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository"/>
</bean>
</beans>