SpringBatch Sample (三)(XML文件操作)
前篇关于Spring Batch的文章,讲述了Spring Batch 对CSV文件的读写操作。 本文将通过一个完整的实例,与大家一起讨论运用Spring Batch对XML文件的读写操作。实例流程是从一个XML文件中读取商品信息,经过简单的处理,写入另外一个XML文件中。
工程结构如下图:
log4j.xml是log处理的配置文件,与本文没有必然联系,再此不做论述。
application.xml文件内容如下:
按 Ctrl+C 复制代码 <?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.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-autowire="byName">
<!-- auto scan path -->
<context:component-scan base-package="com.wanggc.springbatch.sample.xml" />
<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">
</bean>
</beans> 按 Ctrl+C 复制代码
17行是base-spckage的指定,是spring的用法。
19-22行配置的jobLauncher用来启动Job。
24行配置的jobRepository为job提供持久化操作。
26-28行的transactionManager提供事物管理操作。
本文核心配置文件batch.xml内容如下:
按 Ctrl+C 复制代码 <?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.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.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">
</chunk>
</tasklet>
</step>
</job>
<!-- XML文件读取 -->
<bean:bean id="xmlReader"
class="org.springframework.batch.item.xml.StaxEventItemReader" scope="step">
<bean:property name="fragmentRootElementName" value="goods" />
<bean:property name="unmarshaller" ref="tradeMarshaller" />
<bean:property name="resource"
value="file:#{jobParameters['inputFilePath']}"></bean:property>
</bean:bean>
<!-- XML文件写入 -->
<bean:bean id="xmlWriter"
class="org.springframework.batch.item.xml.StaxEventItemWriter" scope="step">
<bean:property name="rootTagName" value="wanggc" />
<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="goods"
value="com.wanggc.springbatch.sample.xml.pojo.Goods" />
<bean:entry key="buyDay" value="java.util.Date"></bean:entry>
</util:map>
</bean:property>
</bean:bean>
</bean:beans> 按 Ctrl+C 复制代码
21-29行配置了Job的基本信息。此Job包含一个Step,Step中包含了基本的读(xmlReader),处理(xmlProcessor),写(xmlWriter)。
32-38行配置了对XML文件读操作。对XML的读是由SpringBatch提供的StaxEventItemReader类来完成。要读取一个XML文件,首先要知道这个文件的存放路径,resource属性就是指定文件路径信息的。知道了文件路径,还需要知道要读取的XML的根节点名称,fragmentRootElementName属性就是指定根节点名称的。知道了根节点名称,还需要知道的一点就是怎么解析这个节点信息,unmarshaller就负责完成解析节点信息,并映射成程序pojo对象。注意,根节点并不是指整个XML文件的根节点,而是指要读取的信息片段的根节点,不管这个节点片段处在哪一层,框架都会遍历到。
49-58行配置了解析XML节点信息的unmarshaller。其中entry的key指定对应根节点名称goods,value指定程序的pojo类,这样,程序就可以将goods节点下的子节点与pojo类(Goods)中的属性去匹配,当匹配到子节点名与pojo类中的属性名相同时,就会将子节点的内容赋值给pojo类的属性。这样就完成了一个根节点的读取,框架会控制循环操作,直到将文件中所有根(goods)节点全部读完为止。这样就完成了XML文件的读操作。
41-47行配置了对XML文件的写操作。与读XML文件一样,要写一个XML文件,也是需要知道这个文件的文件的存放路径的,同样是resource属性提供文件的路径信息。同时,也是需要知道这个文件的跟节点信息的,rootTagName属性提供根节点名信息。注意此处的根节点,指整个文件的跟节点,与读得时候稍有区别,从两个属性的名称上也可以看出。有了上面的信息,完成一个写操作,还需要一个把pojo对象转换成XML片段的工具,由marshaller提供。本文读操作的unmarshaller和写操作的marshaller用的是同一个转换器,因为XStreamMarshaller既提供将节点片段转换为pojo对象功能,同时又提供将pojo对象持久化为xml文件的功能。如果写的内容与读得内容有很大差异,可以另外配置一个转换器。
batch.xml文件配置的对XML文件的读写操作,至于读出来的信息做怎么样的处理再写入文件,通过简单的配置恐怕就无法完成了,就需要我们自己写代码完成了。XMLProcessor类就是完成这个工作的。只要在Job的配置文件中指定到这个类就可以了。XMLProcessor类的内容如下:

package com.wanggc.springbatch.sample.xml; import java.util.Date; import org.springframework.batch.item.ItemProcessor;
import org.springframework.stereotype.Component; import com.wanggc.springbatch.sample.xml.pojo.Goods; /**
* XML文件处理类。
*/
@Component("xmlProcessor")
public class XMLProcessor implements ItemProcessor<Goods, Goods> { /**
* XML文件内容处理。
*
*/
@Override
public Goods process(Goods goods) throws Exception {
// 购入日期变更
goods.setBuyDay(new Date());
// 顾客信息变更
goods.setCustomer(goods.getCustomer() + "顾客!");
// ISIN变更
goods.setIsin(goods.getIsin() + "IsIn");
// 价格变更
goods.setPrice(goods.getPrice() + 1000.112);
// 数量变更
goods.setQuantity(goods.getQuantity() + 100);
// 处理后的数据返回
return goods;
}
}

内容很简单,再此就不做赘述了。要注意的一点就是红背景色的地方。加了此标签无须在batch.xml文件增加对xmlProcessor声明用的bean,可以在job中直接引用,这是Spring的功能。当然,实现这个的前提是要在applicationContext.xml中配置base-package,只有这样才能找到。
工程结构图中的XMLLaunch类用来启动Job。内容如下:

package com.wanggc.springbatch.sample.xml; import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
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 XMLLaunch { /**
* @param args
*/
public static void main(String[] args1) { ApplicationContext context = new ClassPathXmlApplicationContext(
"batch.xml");
JobLauncher launcher = (JobLauncher) context.getBean("jobLauncher");
Job job = (Job) context.getBean("xmlFileReadAndWriterJob"); try {
// JOB实行
JobExecution result = launcher.run(job, new JobParametersBuilder()
.addString("inputFilePath", "C:\\input.xml")
.addString("outputFilePath", "C:\\output.xml")
.toJobParameters());
// 运行结果输出
System.out.println(result.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}

注意其中为Job提供的两个动态参数,以及在配置文件中的用法。
pojo类Goods的内容如下:

package com.wanggc.springbatch.sample.xml.pojo; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date; /**
* 商品信息类.
*/
public class Goods {
/** isin号 */
private String isin;
/** 数量 */
private int quantity;
/** 价格 */
private double price;
/** 客户 */
private String customer;
/** 购入日期 */
private Date buyDay;
/* getter he setter已经删除 */
}

input.xml文件内容如下:
处理结果如下(output.xml):
下次,将和大家一起讨论关于Spring Batch 对固定长内容文件的读写问题。
如果您对本文有意见或者建议,欢迎留言,哪怕是拍砖(^_^)!
欢迎转载,请注明出处!
感谢您的阅读,请关注后续博客!
SpringBatch Sample (三)(XML文件操作)的更多相关文章
- C# XML文件操作
C# XML文件操作 运行环境:Window7 64bit,.NetFramework4.61,C# 6.0: 编者:乌龙哈里 2017-02-09 参考 LINQ to XML System.Xml ...
- 我来讲讲在c#中怎么进行xml文件操作吧,主要是讲解增删改查!
我把我写的四种方法代码贴上来吧,照着写没啥问题. 注: <bookstore> <book> <Id>1</Id> <tate>2010-1 ...
- PHP对XML文件操作之属性与方法讲解
DOMDocument相关的内容. 属性: Attributes 存储节点的属性列表(只读) childNodes 存储节点的子节点列表(只读) dataType 返回此节点的数据类型 Definit ...
- Python 第三天 文件操作(2)
文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开 文件句柄 = file('文件路径', '模式') 注:python中打开文件有两种方式,即:open(...) 和 fi ...
- XML文件操作类--创建XML文件
这个类是在微软XML操作类库上进行的封装,只是为了更加简单使用,包括XML类创建节点的示例. using System; using System.Collections; using System. ...
- Python之路:Python 基础(三)-文件操作
操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 文件句柄 = file('文件路径', '模式') # 还有一种方法open 例1.创建文件 f = file('myfile. ...
- 7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml
数据本地化 A CCUserDefault 系统会在默认路径cocos2d-x-2.2.3\projects\Hello\proj.win32\Debug.win32下生成一个名为UserDef ...
- Python(三)——文件操作
在我们用语言的过程中,比如要往文件内进行读写,那么势必要进行文件操作,那么咋操作呢?用眼睛直接看么?今天就定个小目标,把文件读写那些事扯一扯 文件操作 把大象放进冰箱分几步? 第一步:打开冰箱 第二步 ...
- 2 python第三章文件操作
1.三元运算 三元运算又称三目运算,是对简单的条件语句的简写,如: 简单条件语句: if 条件成立: val = 1 else: val = 2 改成三元运算: val = 1 if 条件成立 els ...
随机推荐
- Hive的用法
1.Hive是Hadoop的一个子项目 利用MapReduce编程技术,实现了部分SQL语句.而且还提供SQL的编程接口.Hive推进Hadoop在数据仓库方面的发展. Hive是一个基于Hadoop ...
- HashSet和ArrayList有什么区别
hashSet存储的是无序,不可重复,无索引 ArrayList存储的是有序,可重复,有索引
- loj 10004 智力大冲浪
智力大冲浪 题目描述: 小伟报名参加中央电视台的智力大冲浪节目.本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元.先不要太高兴!因为这些钱还不一定都是你的.接下来主持人宣布了 ...
- Scheduler & Task & Worker & Thread & Request & Session & Connection of SQL Server
MSSQL一直以来被人们认为简单.好学,但等到大家掌握了入门操作,深入理解起来又觉得非常的“拧巴”,尤其是对用惯了Oracle的同学来说,究其根本原因,无非是MSSQL引入和暴露了太多的概念.细节和理 ...
- Linux CPU信息和使用情况查看(CentOS)
一.CPU信息查看 cat /proc/cpuinfo| grep "physical id"| sort -u | wc -l #查看是物理CPU个数,-u和uniq都是去重作用 ...
- eclipse安装scala环境
1.安装eclipse插件,依次点击Help->Eclipse Marketplace 2.输入scala,点击go,进行搜索 3,出现了Scala IDE4.7X,点击右下方的Install进 ...
- laravel的工厂模式数据填充:
数据表post中的字段结构. database\factory\UserFactory.php $factory->define(App\Post::class,function (Faker ...
- php 处理ftp常用操作与方法
原文地址:https://www.cnblogs.com/longfeiPHP/p/5420632.html $ftp_conn = ftp_connect("192.168.1.230&q ...
- Win10系列:VC++调用自定义组件1
通过20.9.1小节中的代码和步骤编写了一个名为"FilePickerComponent"的WinRT组件,接下来将在上一小节所新建的项目基础上,继续介绍如何在不同的语言所编写的应 ...
- SpringMVC防止表单重复提交
最近公司上线,有同志进行攻击,表当防重复提交也没有弄,交给我 ,本人以前也没弄过,知道大概的思路,但是那样实在是太麻烦了,虽然后面试过使用过滤器加拦截器实现,不过还是有点小麻烦. 后来在网上搜索后发现 ...