一、需求分析
使用Spring Batch对XML文件进行读写操作: 从一个xml文件中读取商品信息, 经过简单的处理, 写入另外一个xml文件中.
二、代码实现
1. 代码结构图:
2. applicationContext.xml
<?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:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd" default-autowire="byName"> <!-- auto scan path --> <context:component-scan base-package="com.zdp" /> <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" /> <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" /> </beans>
base-package: 扫描spring注解
jobLauncher: 启动Job
jobRepository: 为Job提供持久化操作
transactionManager: 提供事务管理操作
3. springBatch.xml
<?xml version="1.0" encoding="UTF-8"?> <bean:beans xmlns="http://www.springframework.org/schema/batch" xmlns:bean="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <bean:import resource="applicationContext.xml" /> <job id="xmlFileReadAndWriterJob"> <step id="xmlFileReadAndWriterStep"> <tasklet> <chunk reader="xmlReader" writer="xmlWriter" processor="xmlProcessor" commit-interval="10" /> </tasklet> </step> </job> <!-- XML文件读取 --> <bean:bean id="xmlReader" class="org.springframework.batch.item.xml.StaxEventItemReader" scope="step"> <bean:property name="fragmentRootElementName" value="product" /> <bean:property name="unmarshaller" ref="tradeMarshaller" /> <bean:property name="resource" value="file:#{jobParameters['inputFilePath']}" /> </bean:bean> <!-- XML文件写入 --> <bean:bean id="xmlWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter" scope="step"> <bean:property name="rootTagName" value="zdp" /> <bean:property name="marshaller" ref="tradeMarshaller" /> <bean:property name="resource" value="file:#{jobParameters['outputFilePath']}" /> </bean:bean> <bean:bean id="tradeMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller"> <bean:property name="aliases"> <util:map id="aliases"> <bean:entry key="product" value="com.zdp.domain.Product" /> <bean:entry key="buyDate" value="java.util.Date" /> </util:map> </bean:property> </bean:bean> </bean:beans>
1. Job包含一个Step,Step中包含了基本的读(xmlReader),处理(xmlProcessor),写(xmlWriter)。
2. xmlReader配置了xml读操作, resource属性是指定文件路径信息的。知道了文件路径。fragmentRootElementName属性是指定根节点名称的. unmarshaller负责完成解析节点信息,并映射成程序pojo对象。
3. tradeMarshaller为解析xml节点, 其中entry的key指定对应根节点名称product,value指定程序的pojo类,这样,程序就可以将product节点下的子节点与pojo类(Product)中的属性去匹配,当匹配到子节点名与pojo类中的属性名相同时,就会将子节点的内容赋值给pojo类的属性。这样就完成了一个根节点的读取,框架会控制循环操作,直到将文件中所有根(product)节点全部读完为止。这样就完成了XML文件的读操作。
4. xmlWriter配置了对XML文件的写操作。resource属性提供文件的路径信息。同时,也是需要知道这个文件的跟节点信息的,rootTagName属性提供根节点名信息。marshaller把pojo对象转换成XML片段的工具。本文读操作的unmarshaller和写操作的marshaller用的是同一个转换器,因为XStreamMarshaller既提供将节点片段转换为pojo对象功能,同时又提供将pojo对象持久化为xml文件的功能。
4. XMLProcessor
/** * XML文件处理类。 */ @Component("xmlProcessor") public class XMLProcessor implements ItemProcessor<Product, Product> { // XML文件内容处理 @Override public Product process(Product product) throws Exception { product.setBuyDate(new Date()); product.setCustomer(product.getCustomer() + "顾客!"); product.setId(product.getId() + "_1"); product.setPrice(product.getPrice() + 1000.0); product.setQuantity(product.getQuantity() + 100); return product; } }5. Product
/** * 实体产品类 */ public class Product { private String id; private int quantity; // 数量 private double price; // 价格 private String customer; // 顾客 private Date buyDate; // 日期 }6. JobLaunch
/** * Test client */ public class JobLaunch { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("springBatch.xml"); JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher"); Job job = (Job) context.getBean("xmlFileReadAndWriterJob"); try { jobLauncher.run(job, new JobParametersBuilder().addString("inputFilePath", "d:\\input.xml") .addString("outputFilePath", "d:\\output.xml") .toJobParameters()); } catch (Exception e) { e.printStackTrace(); } } }
8. output.xml