Spring Batch示例– XML文件到CSV文件

本教程演示了如何使用Spring Batch配置作业,从XML文件读取数据,通过过滤和处理,然后将数据写入CSV文件。内容包括项目设置、依赖、XML读取、Spring Batch核心组件、自定义适配器以及作业执行。
摘要由CSDN通过智能技术生成

在本教程中,我们将向您展示如何配置Spring Batch作业以将XML文件( JAXB2库)读取到csv文件中,并在使用ItemProcessor进行写入之前过滤掉记录。

使用的工具和库

  1. Maven 3
  2. Eclipse 4.2
  3. JDK 1.6
  4. Spring Core 3.2.2。发布
  5. Spring Batch 2.2.0。发布
  6. Spring OXM 3.2.2。发布

PS此示例– XML文件(读取器)–过滤(itemProcessor)– CSV(写入器)。

1.简单的Java项目

1.使用Maven创建一个快速入门Java Project,将其转换并导入Eclipse IDE。

$ mvn archetype:generate -DgroupId=com.mkyong -DartifactId=SpringBatchExample3 
  -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
$ cd SpringBatchExample3/
$ mvn eclipse:eclipse

2.项目依赖

pom.xml声明所有项目依赖项

pom.xml
<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mkyong</groupId>
	<artifactId>SpringBatchExample</artifactId>
	<packaging>jar</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>SpringBatchExample</name>
	<url>http://maven.apache.org</url>

	<properties>
		<jdk.version>1.6</jdk.version>
		<spring.version>3.2.2.RELEASE</spring.version>
		<spring.batch.version>2.2.0.RELEASE</spring.batch.version>
	</properties>

	<dependencies>

		<!-- Spring Core -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- Spring XML to/back object -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- Spring Batch dependencies -->
		<dependency>
			<groupId>org.springframework.batch</groupId>
			<artifactId>spring-batch-core</artifactId>
			<version>${spring.batch.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.batch</groupId>
			<artifactId>spring-batch-infrastructure</artifactId>
			<version>${spring.batch.version}</version>
		</dependency>

	</dependencies>
	<build>
	    <finalName>spring-batch</finalName>
	    <plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-eclipse-plugin</artifactId>
			<version>2.9</version>
			<configuration>
				<downloadSources>true</downloadSources>
				<downloadJavadocs>false</downloadJavadocs>
			</configuration>
		</plugin>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<version>2.3.2</version>
			<configuration>
				<source>${jdk.version}</source>
				<target>${jdk.version}</target>
			</configuration>
		</plugin>
	    </plugins>
	</build>

</project>

3.项目目录结构

查看最终的项目结构,获得下一步的概览。

Spring批处理XML到CSV

4. XML文件

resources/xml/report.xml
<?xml version="1.0" encoding="UTF-8" ?>
<company>
    <record refId="1001">
        <name>mkyong</name>
        <age>31</age>
        <dob>31/8/1982</dob>
        <income>200,000</income>
    </record>
    <record refId="1002">
        <name>kkwong</name>
        <age>30</age>
        <dob>26/7/1983</dob>
        <income>100,999</income>
    </record>
    <record refId="1003">
        <name>joel</name>
        <age>29</age>
        <dob>21/8/1984</dob>
        <income>1,000,000</income>
    </record>
    <record refId="1004">
        <name>leeyy</name>
        <age>29</age>
        <dob>21/3/1984</dob>
        <income>80,000.89</income>
    </record>
</company>

5.读取XML文件

在此示例中,我们使用Jaxb2Marshaller将XML值和属性映射到对象。

resources/spring/batch/jobs/job-report.xml
<!-- ...... -->
    <bean id="xmlItemReader" 
        class="org.springframework.batch.item.xml.StaxEventItemReader">
	<property name="fragmentRootElementName" value="record" />
	<property name="resource" value="classpath:xml/report.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.mkyong.model.Report</value>
	  </list>
	</property>
    </bean>

注释Report以告知哪个XML值映射到哪个字段。

Report.java
package com.mkyong.model;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.mkyong.adapter.JaxbBigDecimalAdapter;
import com.mkyong.adapter.JaxbDateAdapter;

@XmlRootElement(name = "record")
public class Report {

	private int refId;
	private String name;
	private int age;
	private Date dob;
	private BigDecimal income;

	@XmlAttribute(name = "refId")
	public int getRefId() {
		return refId;
	}

	public void setRefId(int refId) {
		this.refId = refId;
	}

	@XmlElement(name = "age")
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@XmlElement
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@XmlJavaTypeAdapter(JaxbDateAdapter.class)
	@XmlElement
	public Date getDob() {
		return dob;
	}

	public void setDob(Date dob) {
		this.dob = dob;
	}

	@XmlJavaTypeAdapter(JaxbBigDecimalAdapter.class)
	@XmlElement
	public BigDecimal getIncome() {
		return income;
	}

	public void setIncome(BigDecimal income) {
		this.income = income;
	}

	// for csv file only
	public String getCsvDob() {

		SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		return dateFormat.format(getDob());

	}

}

在JAXB2中,那些“复杂”的数据类型(如DateBigDecimal即使被注释,也不会自动映射到该字段。

为了使JAXB2支持Date转换,您需要创建一个自定义的Adapter来手动处理Date format ,然后通过@XmlJavaTypeAdapter附加该适配器。

JaxbDateAdapter.java
package com.mkyong.adapter;

import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.bind.annotation.adapters.XmlAdapter;


public class JaxbDateAdapter extends XmlAdapter<String, Date> {

	private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");

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

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

}

BigDecimal相同,XML的income元素中的逗号“,”会引起转换问题,您还需要一个自定义适配器来处理它。

JaxbBigDecimalAdapter.java
package com.mkyong.adapter;

import java.math.BigDecimal;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class JaxbBigDecimalAdapter extends XmlAdapter<String, BigDecimal> {

	@Override
	public String marshal(BigDecimal obj) throws Exception {
		return obj.toString();
	}

	@Override
	public BigDecimal unmarshal(String obj) throws Exception {
		return new BigDecimal(obj.replaceAll(",", ""));
	}

}

6. Spring批处理核心设置

定义jobRepositoryjobLauncher

resources/spring/batch/config/context.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">

    <!-- stored job-meta in memory --> 
    <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>

7.Spring批作业

Spring批处理作业,读取report.xml文件,将其映射到Report对象,并将其写入csv文件。 阅读评论,应该不言自明。

resources/spring/batch/jobs/job-report.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="reportJob">
	<batch:step id="step1">
	<batch:tasklet>
		<batch:chunk reader="xmlItemReader" 
			writer="cvsFileItemWriter" processor="filterReportProcessor"
			commit-interval="1">
		</batch:chunk>
	</batch:tasklet>
	</batch:step>
  </batch:job>

  <!-- Filtering process -->
  <bean id="filterReportProcessor" class="com.mkyong.processor.FilterReportProcessor" />

  <bean id="xmlItemReader" 
        class="org.springframework.batch.item.xml.StaxEventItemReader">
	<property name="fragmentRootElementName" value="record" />
	<property name="resource" value="classpath:xml/report.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.mkyong.model.Report</value>
	</list>
    </property>
  </bean>

  <bean id="cvsFileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">
	<!-- write to this csv file -->
	<property name="resource" value="file:cvs/report.csv" />
	<property name="shouldDeleteIfExists" value="true" />

	<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="refId, name, age, csvDob, income" />
		   </bean>
		</property>
	   </bean>
	</property>
  </bean>

</beans>

8. Spring Batch – ItemProcessor

在Spring批处理中,将在写入任何资源之前触发有线Processor ,因此,这是处理任何转换,过滤和业务逻辑的最佳位置。 在此示例中,如果Report对象的age等于30,则它将被忽略(不写入CSV文件)。

FilterReportProcessor.java
package com.mkyong.processor;

import org.springframework.batch.item.ItemProcessor;
import com.mkyong.model.Report;

//run before writing
public class FilterReportProcessor implements ItemProcessor<Report, Report> {

	@Override
	public Report process(Report item) throws Exception {

		//filter object which age = 30
		if(item.getAge()==30){
			return null; // null = ignore this object
		}
		return item;
	}

}

9.运行

运行批处理作业的最简单方法。

App.java
package com.mkyong;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
  public static void main(String[] args) {

	String[] springConfig  = 
	{	
		"spring/batch/config/context.xml",
		"spring/batch/jobs/job-report.xml" 
	};
		
	ApplicationContext context = 
		new ClassPathXmlApplicationContext(springConfig);
		
	JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
	Job job = (Job) context.getBean("reportJob");

	try {

		JobExecution execution = jobLauncher.run(job, new JobParameters());
		System.out.println("Exit Status : " + execution.getStatus());

	} catch (Exception e) {
		e.printStackTrace();
	}

	System.out.println("Done");

  }
}

输出。 XML值将插入到csv文件中。

csv/report.csv
1001,mkyong,31,31/08/1982,200000
1003,joel,29,21/08/1984,1000000
1004,leeyy,29,21/03/1984,80000.89
输出

下载源代码

下载它– SpringBatch-XML-CSV-Example.zip (81 kb)

参考文献

  1. Spring Batch ItemReaders和ItemWriters
  2. JAXB自定义绑定– Java.util.Date
  3. 如何使用FlatFileItemWriter?
  4. FlatFileItemWriter JavaDoc

翻译自: https://mkyong.com/spring-batch/spring-batch-example-xml-file-to-csv-file/

Spring Batch是一个用于大规模批量处理的开源框架,可以帮助我们简化和规范化批量作业的开发。在Spring Batch中获取多个文件示例可以通过以下步骤来完成: 首先,我们需要配置Spring Batch的Job和Step。在Job配置中,我们可以定义多个Step,每个Step可以处理一个文件。在Step配置中,我们可以定义ItemReader、ItemProcessor和ItemWriter等组件,来完成文件读取、数据处理和结果写入等功能。 其次,我们需要编写ItemReader的实现类来读取文件。在多文件的情况下,我们可以通过Loop资源配置来遍历不同的文件。例如,可以使用MultiResourceItemReader来设置多个文件路径,并通过设置同一个Delegate对象来处理每个文件读取。 然后,我们可以编写ItemProcessor的实现类来处理读取到的数据。在多文件的情况下,我们可以使用文件名称作为数据的一部分,以便在后续的处理中对数据进行分类或区分。 最后,我们可以编写ItemWriter的实现类来将处理后的结果写入到目标文件中。在多文件的情况下,我们可以使用不同的文件名称来区分不同的结果文件。 综上所述,通过以上配置和编码,我们可以实现Spring Batch获取多个文件示例。通过配置Job和Step,使用MultiResourceItemReader处理多个文件读取,使用ItemProcessor处理数据,最后使用ItemWriter将结果写入到相应的文件中。这样,我们就可以实现在Spring Batch中处理多个文件的任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值