Batch

Spring Batch ClassifierCompositeItemWriter Example

This is an in-depth article related to the Spring Batch Classifier with ClassifierCompositeItemWriter.

1. Introduction

Spring Batch is a processing framework designed for the robust execution of jobs. Spring Batch Framework is an open-source library for batch processing. Batch Processing is the execution of a series of jobs. Spring Batch has classes and APIs to read/write resources, job creation, job metadata storage, job data persistence, transaction management, job processing statistics, job restart, and partitioning techniques to process high-volume of data. It has a job repository that takes care of scheduling and job interaction. A job consists of multiple steps. Each step has the sequence of reading job metadata and processing the input to write the output.

Spring batch is based on the traditional batch architecture. In the traditional batch framework, a job repository performs the work of scheduling and interacting with the job. The framework handles the low-level storage work of handling the jobs.

2. Spring Batch ClassifierCompositeItemWriter

2.1 Prerequisites

Java 8 or 9 is required on the Linux, windows, or mac operating system. Maven 3.6.1 is required for building the spring batch application.

2.2 Download

You can download Java 8 can be downloaded from the Oracle web site . Apache Maven 3.6.1 can be downloaded from Apache site. Spring framework latest releases are available from the spring website.

2.3 Setup

You can set the environment variables for JAVA_HOME and PATH. They can be set as shown below:

Environment Setup for Java

JAVA_HOME="/desktop/jdk1.8.0_73"
export JAVA_HOME
PATH=$JAVA_HOME/bin:$PATH
export PATH

The environment variables for maven are set as below:Environment Setup for Maven

Run Command

JAVA_HOME="/jboss/jdk1.8.0_73″
export M2_HOME=/users/bhagvan.kommadi/Desktop/apache-maven-3.6.1
export M2=$M2_HOME/bin
export PATH=$M2:$PATH

2.4 Building the application

2.4.1 Spring

You can start building Spring applications using the Spring Boot framework. Spring Boot has a minimal configuration of Spring. Spring Boot has features related to security, tracing, application health management, and runtime support for webservers. Spring configuration is done through maven pom.xml. The XML configuration is shown as below:

Spring Configuration

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
  
    <groupId>org.springframework</groupId>
    <artifactId>spring-helloworld</artifactId>
    <version>0.1.0</version>
  
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>
  
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
  
    <properties>
        <java.version>1.8</java.version>
    </properties>
  
  
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  
</project>

You can create a HelloWorldController class as the web controller. The class is annotated using @RestController. Rest Controller is used to handling requests in Spring Model View Controller framework. Annotation @RequestMapping is used to annotate the index() method. The code for the HelloWorldController class is shown below:

HelloWorld Controller

package helloworld;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
  
@RestController
public class HelloWorldController {
      
    @RequestMapping("/")
    public String index() {
        return "Hello World\n";
    }
      
}

HelloWorldApp is created as the Spring Boot web application. When the application starts, beans, ​and settings are wired up dynamically. They are applied to the application context. The code for HelloWorldApp class is shown below:

HelloWorld App

package helloworld;
import java.util.Arrays;
  
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
  
@SpringBootApplication
public class HelloWorldApp {
      
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(HelloWorldApp.class, args);
          
        System.out.println("Inspecting the beans");
          
        String[] beans = ctx.getBeanDefinitionNames();
        Arrays.sort(beans);
        for (String name : beans) {
            System.out.println("Bean Name" +name);
        }
    }
  
}

Maven is used for building the application. The command below builds the application.

Maven Build Command

mvn package

The output of the executed command is shown below.

ClassifierCompositeItemWriter - Maven Build
Maven Build

The jar file spring-helloworld-0.1.0.jar is created. The following command is used for executing the jar file.

Run Command

java -jar target/spring-helloworld-0.1.0.jar

The output of the executed command is shown below.

ClassifierCompositeItemWriter - Spring Beans
Spring Beans

Curl command is invoked on the command line for the execution of index method. The method returns a String “Hello World” text. @RestController aggregates the two annotations @Controller and @ResponseBody. This results in returning data. The ouput is shown as below.

ClassifierCompositeItemWriter - Curl Command
Curl Command

2.5 Spring Batch

Spring Batch is a lightweight, comprehensive batch framework. Developers can use it to create batch applications. Batch applications are designed to handle the daily and end of the daily operations of the enterprise. It has features as mentioned below:

  • Large Data Processing
  • Logging
  • Tracing
  • Resource Management
  • Job Processing
  • Transaction management
  • Chunk based processing
  • Declarative I/O
  • Start/Stop/Restart
  • Retry/Skip
  • Web-based administration interface

Let us start looking at creation of a Spring batch job with Batch Classifier and Composite Item writer.

2.5.1 Spring Batch Classifier Composite Item Writer

Spring Batch decorators are used to classify the data to write to multiple destinations. Batch decorators are based on design patterns. Item Reader and ItemWriter are batch decorators. Additional functionality can be added to the ItemReader and ItemWriters. The data can be saved in a database, CSV, or XML file.

ClassifierCompositeItem Writer is based on a router pattern. This class is thread-safe. It helps in writing multiple items to different destinations. The code implementation of EmployeeClassifier class is shown below:

EmployeeClassifier

package org.javacodegeeks.batch.decorator.classifier;

import org.springframework.batch.item.ItemWriter;
import org.springframework.classify.Classifier;

import org.javacodegeeks.batch.decorator.model.Employee;

public class EmployeeClassifier implements Classifier<Employee, ItemWriter> {

	private static final long serialVersionUID = 1L;
	
	private ItemWriter evenItemWriter;
	private ItemWriter oddItemWriter;

	public EmployeeClassifier(ItemWriter evenItemWriter, ItemWriter oddItemWriter) {
		this.evenItemWriter = evenItemWriter;
		this.oddItemWriter = oddItemWriter;
	}

	@Override
	public ItemWriter classify(Employee employee) {
		return employee.getId() % 2 == 0 ? evenItemWriter : oddItemWriter;
	}
}

The code below shows the Employee class which is part of the model.

Employee Class

package org.javacodegeeks.batch.decorator.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class Employee {

	private Long id;
	private String firstName;
	private String lastName;
	private String birthdate;
}

The database table is created for employee in employeedb. Below is the create sql for the database.

Employee sql

CREATE TABLE 'employeedb'.'employee' (
	'id' MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
	'firstName' VARCHAR(255) NULL,
	'lastName' VARCHAR(255) NULL,
	'birthdate' VARCHAR(255) NULL,
PRIMARY KEY ('id')
) AUTO_INCREMENT=1;

The data can be created using the sql script below.

Employee table data sql

INSERT INTO `employeedb`.`employee` (`id`, `firstName`, `lastName`,`birthdate`) VALUES ('1', 'john', 'smith','10-11-1962 10:10:10');
INSERT INTO `employeedb`.`employee` (`id`, `firstName`, `lastName`,`birthdate`) VALUES ('2', 'george', 'kinsey','11-01-1982 10:10:10');
INSERT INTO `employeedb`.`employee` (`id`, `firstName`, `lastName`,`birthdate`) VALUES ('3', 'thomas', 'durham','17-06-1953 10:10:10');

SpringJobConfiguration class code is shown below:

SpringJobConfiguration

package org.javacodegeeks.batch.decorator.config;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.database.JdbcPagingItemReader;
import org.springframework.batch.item.database.Order;
import org.springframework.batch.item.database.support.MySqlPagingQueryProvider;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.support.ClassifierCompositeItemWriter;
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.FileSystemResource;
import org.springframework.oxm.xstream.XStreamMarshaller;

import org.javacodegeeks.batch.decorator.aggregator.CustomLineAggregator;
import org.javacodegeeks.batch.decorator.classifier.EmployeeClassifier;
import org.javacodegeeks.batch.decorator.mapper.EmployeeRowMapper;
import org.javacodegeeks.batch.decorator.model.Employee;

@Configuration
public class SpringJobConfiguration {

	@Autowired
	private JobBuilderFactory jobBuilderFactory;

	@Autowired
	private StepBuilderFactory stepBuilderFactory;

	@Autowired
	private DataSource dataSource;

	@Bean
	public JdbcPagingItemReader customerPagingItemReader() {

	

		JdbcPagingItemReader reader = new JdbcPagingItemReader();
		reader.setDataSource(this.dataSource);
		reader.setFetchSize(1000);
		reader.setRowMapper(new EmployeeRowMapper());

        Map sortKeys = new HashMap();
		sortKeys.put("id", Order.ASCENDING);

		
		MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
		queryProvider.setSelectClause("id, firstName, lastName, birthdate");
		queryProvider.setFromClause("from employee");
		queryProvider.setSortKeys(sortKeys);
		reader.setQueryProvider(queryProvider);
		return reader;
	}

	@Bean
	public FlatFileItemWriter jsonItemWriter() throws Exception {

		String customerOutputPath = File.createTempFile("employeeOutput", ".out").getAbsolutePath();
		System.out.println(">> Output Path = " + customerOutputPath);
		FlatFileItemWriter writer = new FlatFileItemWriter();
		writer.setLineAggregator(new CustomLineAggregator());
		writer.setResource(new FileSystemResource(customerOutputPath));
		writer.afterPropertiesSet();
		return writer;
	}

	@Bean
	public StaxEventItemWriter xmlItemWriter() throws Exception {

		String customerOutputPath = File.createTempFile("employeeOutput", ".out").getAbsolutePath();
		System.out.println(">> Output Path = " + customerOutputPath);
		Map aliases = new HashMap();
		aliases.put("employee", Employee.class);
		XStreamMarshaller marshaller = new XStreamMarshaller();
		marshaller.setAliases(aliases);

		
		StaxEventItemWriter writer = new StaxEventItemWriter();
		writer.setRootTagName("employees");
		writer.setMarshaller(marshaller);
		writer.setResource(new FileSystemResource(customerOutputPath));
		writer.afterPropertiesSet();
		return writer;
	}

	@Bean
	public ClassifierCompositeItemWriter classifierEmployeeCompositeItemWriter() throws Exception {
		ClassifierCompositeItemWriter compositeItemWriter = new ClassifierCompositeItemWriter();
		compositeItemWriter.setClassifier(new EmployeeClassifier(xmlItemWriter(), jsonItemWriter()));
		return compositeItemWriter;
	}

	@Bean
	public Step step1() throws Exception {
		return stepBuilderFactory.get("step1")
				.chunk(10)
				.reader(customerPagingItemReader())
				.writer(classifierEmployeeCompositeItemWriter())
				.stream(xmlItemWriter())
				.stream(jsonItemWriter())
				.build();
	}

	@Bean
	public Job job() throws Exception {
		return jobBuilderFactory.get("job")
				.start(step1())
				.build();
	}

}

SpringBatchApplication class code is shown below:

SpringBatchApplication Class

package org.javacodegeeks.batch.decorator;

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.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableBatchProcessing
public class SpringBatchApplication 
					implements CommandLineRunner {
	@Autowired
	private JobLauncher jobLauncher;

	@Autowired
	private Job job;
	
	public static void main(String[] args) {
		SpringApplication.run(SpringBatchApplication.class, args);
	}
	
	@Override
	public void run(String... args) throws Exception {
		JobParameters jobParameters = new JobParametersBuilder()
                .addString("JobId", String.valueOf(System.currentTimeMillis()))
				.addDate("date", new Date())
                .addLong("time",System.currentTimeMillis()).toJobParameters();
		
		JobExecution execution = jobLauncher.run(job, jobParameters);
		System.out.println("STATUS :: "+execution.getStatus());
	}
}

Maven pom.xml is shown below which is used for the build and execution of the project.

Maven pom.xml

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.2.RELEASE</version>
		<relativePath />
	</parent>

	<groupId>org.javacodegeeks</groupId>
	<artifactId>batch-classifier</artifactId>
	<name>batch-classifier</name>
	<packaging>jar</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-batch</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<!-- Spring OXM -->

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
		</dependency>

		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<dependency>
			<groupId>com.thoughtworks.xstream</groupId>
			<artifactId>xstream</artifactId>
			<version>1.4.7</version>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.batch</groupId>
			<artifactId>spring-batch-test</artifactId>
			<scope>test</scope>
		</dependency>

	</dependencies>
</project>

Code can be built using the below command.

Build Command

mvn package

The output of the command is shown below:

Build Command Output

apples-MacBook-Air:batchclassifier bhagvan.kommadi$ mvn package
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------------------------------
[INFO] Building batch-classifier 2.2.2.RELEASE
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ batch-classifier ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 2 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ batch-classifier ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 6 source files to /Users/bhagvan.kommadi/Desktop/JavacodeGeeks/Code/springbatchclassifier/batchclassifier/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ batch-classifier ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/bhagvan.kommadi/Desktop/JavacodeGeeks/Code/springbatchclassifier/batchclassifier/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ batch-classifier ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/bhagvan.kommadi/Desktop/JavacodeGeeks/Code/springbatchclassifier/batchclassifier/target/test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ batch-classifier ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.javacodegeeks.batch.decorator.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.005 s - in org.javacodegeeks.batch.decorator.AppTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] 
[INFO] --- maven-jar-plugin:3.1.2:jar (default-jar) @ batch-classifier ---
[INFO] Building jar: /Users/bhagvan.kommadi/Desktop/JavacodeGeeks/Code/springbatchclassifier/batchclassifier/target/batch-classifier-2.2.2.RELEASE.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.690 s
[INFO] Finished at: 2020-11-03T21:56:14+05:30
[INFO] ------------------------------------------------------------------------
apples-MacBook-Air:batchclassifier bhagvan.kommadi$

Code can be executed using the command shown below:

Run Command

mvn spring-boot:run

The output of the above command is shown below:

Run Command Output

apples-MacBook-Air:batchclassifier bhagvan.kommadi$ mvn spring-boot:run
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------------------------------
[INFO] Building batch-classifier 2.2.2.RELEASE
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] >>> spring-boot-maven-plugin:2.2.2.RELEASE:run (default-cli) > test-compile @ batch-classifier >>>
[INFO] 
[INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ batch-classifier ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 2 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ batch-classifier ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ batch-classifier ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/bhagvan.kommadi/Desktop/JavacodeGeeks/Code/springbatchclassifier/batchclassifier/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ batch-classifier ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] <<< spring-boot-maven-plugin:2.2.2.RELEASE:run (default-cli) < test-compile @ batch-classifier <<> Output Path = /var/folders/cr/0y892lq14qv7r24yl0gh0_dm0000gp/T/employeeOutput8605284055436216810.out
>> Output Path = /var/folders/cr/0y892lq14qv7r24yl0gh0_dm0000gp/T/employeeOutput913271422004184523.out
2020-11-03 21:58:54.079  INFO 4105 --- [           main] o.s.b.c.r.s.JobRepositoryFactoryBean     : No database type set, using meta data indicating: MYSQL
2020-11-03 21:58:54.116  INFO 4105 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : No TaskExecutor has been set, defaulting to synchronous executor.
2020-11-03 21:58:54.246  INFO 4105 --- [           main] o.j.b.decorator.SpringBatchApplication   : Started SpringBatchApplication in 3.051 seconds (JVM running for 3.964)
2020-11-03 21:58:54.249  INFO 4105 --- [           main] o.s.b.a.b.JobLauncherCommandLineRunner   : Running default command line with: []
2020-11-03 21:58:54.431  INFO 4105 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job]] launched with the following parameters: [{}]
2020-11-03 21:58:54.507  INFO 4105 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Step already complete or not restartable, so no action to execute: StepExecution: id=1, version=3, name=step1, status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0, exitDescription=
2020-11-03 21:58:54.526  INFO 4105 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 33ms
2020-11-03 21:58:54.572  INFO 4105 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job]] launched with the following parameters: [{JobId=1604420934528, date=1604420934528, time=1604420934528}]
2020-11-03 21:58:54.595  INFO 4105 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
2020-11-03 21:58:54.741  INFO 4105 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [step1] executed in 144ms
2020-11-03 21:58:54.758  INFO 4105 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job]] completed with the following parameters: [{JobId=1604420934528, date=1604420934528, time=1604420934528}] and the following status: [COMPLETED] in 180ms
STATUS :: COMPLETED
2020-11-03 21:58:54.764  WARN 4105 --- [extShutdownHook] o.s.b.f.support.DisposableBeanAdapter    : Destroy method 'close' on bean with name 'xmlItemWriter' threw an exception: java.lang.NullPointerException
2020-11-03 21:58:54.765  INFO 4105 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-11-03 21:58:54.773  INFO 4105 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  8.810 s
[INFO] Finished at: 2020-11-03T21:58:54+05:30
[INFO] ------------------------------------------------------------------------
apples-MacBook-Air:batchclassifier bhagvan.kommadi$

The xml output is shown below:

XML Output

<?xml version="1.0" encoding="UTF-8"?
><employees>
<employee>
<id>2</id>
<firstName>george</firstName>
<lastName>kinsey</lastName>
<birthdate>11-01-1982 10:10:10</birthdate>
</employee>
</employees>

The json output is presented below:

JSON Output

{"id":1,"firstName":"john","lastName":"smith","birthdate":"10-11-1962 10:10:10"}
{"id":3,"firstName":"thomas","lastName":"durham","birthdate":"17-06-1953 10:10:10"}

3. Download the Source Code

That was an article related to the Spring Batch Classifier with ClassifierCompositeItemWriter.

Download
You can download the full source code of this example here: Spring Batch ClassifierCompositeItemWriter Example

Bhagvan Kommadi

Bhagvan Kommadi is the Founder of Architect Corner & has around 20 years’ experience in the industry, ranging from large scale enterprise development to helping incubate software product start-ups. He has done Masters in Industrial Systems Engineering at Georgia Institute of Technology (1997) and Bachelors in Aerospace Engineering from Indian Institute of Technology, Madras (1993). He is member of IFX forum,Oracle JCP and participant in Java Community Process. He founded Quantica Computacao, the first quantum computing startup in India. Markets and Markets have positioned Quantica Computacao in ‘Emerging Companies’ section of Quantum Computing quadrants. Bhagvan has engineered and developed simulators and tools in the area of quantum technology using IBM Q, Microsoft Q# and Google QScript. He has reviewed the Manning book titled : "Machine Learning with TensorFlow”. He is also the author of Packt Publishing book - "Hands-On Data Structures and Algorithms with Go".He is member of IFX forum,Oracle JCP and participant in Java Community Process. He is member of the MIT Technology Review Global Panel.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button