文档章节

common digester-入门

gzh412163
 gzh412163
发布于 2014/06/20 14:01
字数 1876
阅读 78
收藏 0
点赞 0
评论 0


Commons-Digester简介




一.历史

Digester本来仅仅是Jakarta Struts中的一个工具,用于处理struts-config.xml配置文件。显然,将XML文件转换成相应的Java对象是一项很通用的功能,这个工具理应具有更广泛的用途,所以很快它就在Jakarta Commons项目(用于提供可重用的Java组件库)中有了一席之地。



二.几个要点

简言之,Digester由"事件"驱动,通过调用预定义的规则操作对象栈,将XML文件转换为Java对象。工作原理如下:

Digester底层采用SAX解析XML文件,所以很自然的,对象转换由"事件"驱动,即在识别出特定XML元素时(实际被细分为begin、body、end、finish四个时点),将执行特定的动作,比如创建特定的Java对象,或调用特定对象的方法等。此处的XML元素根据匹配模式(matching pattern)识别,而相关操作由规则(rule)定义。在转换过程中,Digester维持了一个对象栈,可以看作对象转换的工作台,用来存放转换中生成的、或是为转换临时创建的Java对象。对输入XML文件作了一趟完整的扫描后,对象栈的栈顶元素即为目标对象。由于Digester屏蔽了SAX解析的细节,使用者仅需关注转换操作本身,大大简化了转换操作。


对使用者而言,Digester的核心在于匹配模式与规则(matching pattern + rule)。


匹配规则示例如下:
   <a>          -- Matches pattern "a"
     <b>        -- Matches pattern "a/b"
       <c/>     -- Matches pattern "a/b/c"
       <c/>     -- Matches pattern "a/b/c"
     </b>
     <b>        -- Matches pattern "a/b"
       <c/>     -- Matches pattern "a/b/c"
       <c/>     -- Matches pattern "a/b/c"
       <c/>     -- Matches pattern "a/b/c"
     </b>
   </a>


Digester提供了一些编程中经常用到的规则(rule),以下五类九个rule较为常用:

A:对象创建
1.ObjectCreateRule   当begin()方法被调用时, 此rule创建相应Java对象, 并将其push到Digester的对象栈上。当end()方法被调用时, 栈顶对象将被pop, Digester内所有对该对象的引用都将失效。
2.FactoryCreateRule     创建Java对象的另一种选择。当待创建的Java对象没有无参构造函数,或需要在创建时需要进行额外的设置时,需要用此rule。


B:属性设置
3.SetPropertiesRule     当begin()方法被调用时, Digester使用标准的Java反射API,将栈顶对象的属性设置为XML元素的同名属性值。
4.SetPropertyRule     当begin()方法被调用时, Digester调用栈顶对象某指定属性的设置方法,设置其值。


C:父子关系管理
5.SetNextRule     当end()方法被调用时, Digester将栈顶元素设置进次栈顶元素中(调用相应的设置方法)。
6.SetTopRule     当end()方法被调用时, Digester将次栈顶元素设置进栈顶元素中(调用相应的设置方法)。


D:任意方法调用
7.CallMethodRule     当end()方法被调用时, Digester将调用栈顶元素指定名称的方法。除了方法名外,此rule还需要配置参数数目,参数类型。参数值一般通过CallParamRule得到。
8.CallParamRule     此rule内嵌于CallParamRule中,按顺序(相对于0)定义了CallParamRule中参数值的来源,可选的来源包括当前XML元素的属性或内容。


E:其它
9.NodeCreateRule     将XML文件树的一部分转换为DOM节点,并push到Digester的对象栈上。


在基本使用中,使用者通过调用Digester类的相关方法,来创建匹配模式与规则的映射序列。比如,调用addSetProperties(String pattern),向Digester中加入SetPropertiesRule。




三.如何使用?

基本步骤如下:
1.创建Digester对象实例。
2.设置该Digester对象的配置属性(可选)。
3.将需要的初始对象push到该Digester对象的对象栈上(可选)。
4.需要注册所有的XML元素匹配模式与处理规则之间的映射关系。
5.用digester.parse()解析的XML文档对象,得到目标对象。



下面是一个简单示例:
1.foo.xml   数据源文件
2.Foo.java   目标Java对象
3.Bar.java   目标Java对象
4.Entry.java   调用Digester的入口类

【foo.xml】
<?xml version="1.0" encoding="GBK"?>
<foo name="The Parent">
     <bar id="123" title="The First Child"/>
     <bar id="456" title="The Second Child"/>
</foo>

【Foo.java】
package org.easev.digester;

import java.util.HashMap;
import java.util.Iterator;

public class Foo {

     private String name;

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

     public String getName() {
         return name;
     }

     private HashMap bars = new HashMap();

     public void addBar(Bar bar) {
         bars.put(String.valueOf(bar.getId()), bar);
     }

     public Bar findBar(int id) {
         return (Bar) bars.get(String.valueOf(id));
     }

     public Iterator getBars() {
         return bars.keySet().iterator();
     }
}

【Bar.java】
package org.easev.digester;

public class Bar {

     private int id;

     public int getId() {
         return id;
     }

     public void setId(int id) {
         this.id = id;
     }

     private String title;

     public String getTitle() {
         return title;
     }

     public void setTitle(String title) {
         this.title = title;
     }
}

【Entry.java】
package org.easev.digester;

import java.io.File;
import java.util.Iterator;

import org.apache.commons.digester.Digester;

public class Entry {

     public static void main(String[] args) throws Exception {
         //相对路径定义与包名相关
         File input = new File("org/easev/digester/foo.xml");
         Digester digester = new Digester();
         digester.setValidating(false);

         //完整类名定义,包名改变时需做相应变化
         digester.addObjectCreate("foo", "org.easev.digester.Foo");
         digester.addSetProperties("foo");
         digester.addObjectCreate("foo/bar", "org.easev.digester.Bar");
         digester.addSetProperties("foo/bar");
         digester.addSetNext("foo/bar", "addBar", "org.easev.digester.Bar");

         Foo foo = (Foo) digester.parse(input);

         //测试装载是否成功
         Iterator iter = foo.getBars();
         while (iter.hasNext()) {
             System.out.println((String) iter.next());
         }
     }

}

匹配模式没有什么文章好做,那么下面要讨论的就必然是规则了。在基本的使用方式下,Digester虽然使用XML文件定义Java对象的状态,提高了系统的灵活性,但是匹配模式与规则的映射序列(装载逻辑)仍然通过硬编码来定义,这种方式不易修改与重用。所以Digester还提供了一种高级的使用方式,用一个XML文件定义Java对象的状态(数据源文件),用另一个XML文件定义装载数据源文件的装载逻辑。


这样,对象的装载过程分成了两步:
1.装载逻辑的"装载",其结果表现为定义了rule的Digester;
2.根据上一步得到的Digester,装载目标对象。

套用上面的一个例子,增加了rule.xml,并改写了Entry.java

【rule.xml】
<?xml version='1.0'?>
<!DOCTYPE digester-rules 
   PUBLIC "-//Jakarta Apache //DTD digester-rules XML V1.0//EN" 
     "">

<digester-rules>
   <pattern value="foo">
     <object-create-rule classname="org.easev.digester.Foo"/>
     <set-properties-rule/>
     <pattern value="bar">
       <object-create-rule classname="org.easev.digester.Bar"/>
       <set-properties-rule/>
       <set-next-rule methodname="addBar"/>
     </pattern>
   </pattern>
</digester-rules>

【Entry.java】
package org.easev.digester;

import java.io.File;
import java.util.Iterator;

import org.apache.commons.digester.Digester;

public class Entry {

     public static void main(String[] args) throws Exception {
         //相对路径定义与包名相关
         File data = new File("org/easev/digester/foo.xml");
         File rule = new File("org/easev/digester/rule.xml");
         Digester digester = DigesterLoader.createDigester(rule.toURL());
         Foo foo = (Foo) digester.parse(data);
        
         //测试装载是否成功
         Iterator iter = foo.getBars();
         while (iter.hasNext()) {
             System.out.println((String) iter.next());
         }
     }

}

我们可以看到,使用Digester的代码变得相当简洁,而要付出的代价就是为装载逻辑写一个配置文件。



四.其他的替代技术

除了Digester之外,当然还有其它的方法来实现Java对象的绑定与装载:
1.java.util.Properties,简单的配置属性(比如数据库连接信息),可以写在properties文件中,调用Properties对象的load(InputStream)方法将配置中的健值对加载到Properties对象中。这种方式一般仅适用于简单的配置信息的加载。
2.JAXB,Java Architecture for XML Binding,在Java Web Services Developer Pack V 1.1中提供了一个参考实现。使用这种方式时,除了提供数据源XML文件之外,还必须提供相应的Schema文件。加载前,首先用Binding Compiler将Schema转换得到目标Java类的接口与实现,然后再调用Unmarshaller或Marshaller将数据源XML文件信息加载到Java对象中,或将设置的Java对象数据导出为XML文件。 
3.XPath 
4.JaxMe



本文转载自:http://hi.baidu.com/leilei1334/item/c9eced0f052ed36dd55a1178

共有 人打赏支持
gzh412163
粉丝 1
博文 66
码字总数 12796
作品 0
深圳
使用Jakarta Common Digester解析XML的简单例子

其中 digester.addSetProperties 用来获取节点中的属性值。即<root title="网址">。 若是<root><title>网址</title></root>的形式,可以用digester.addBeanPropertySetter方法 使用Digester可......

墙头草 ⋅ 2011/06/29 ⋅ 0

tomcat启动失败

2013-11-13 10:16:03 org.apache.catalina.core.AprLifecycleListener init 信息: The Apache Tomcat Native library which allows optimal performance in production environments was no......

Beackbao ⋅ 2013/11/13 ⋅ 2

tomcat6.0.x启动过程-tomcat 6.x 源码阅读

2013-09-07 周末来啊,宅的日子又到了...我们知道tomcat的基本是容器,通过容器来完成servlet容器的设计。从上一篇blog中看到了tomcat的结构框架图,图中容器嵌套,组件组合,tomcat如何设置...

douglaswei ⋅ 2013/09/07 ⋅ 2

struts1.* 异常处理机制

几个重要类的说明 ActionServlet struts的核心类,用于初始化struts配置文件,处理发送到action的请求; ModuleConfig struts配置文件信息加载的接口,ModuleConfigImpl是接口的默认实现,可...

STG0825 ⋅ 2013/08/29 ⋅ 0

Apache Commons Digester 3.0 发布

Apache Commons Digester 3.0 几乎重写了整个 Digester 实现,包括一个统一的加载器、可重用的 Digester 配置以及使用 EDSL 定义的表达式规则、改进了错误报告信息等。 除此之外,还包括以下...

红薯 ⋅ 2011/07/07 ⋅ 0

Apache Commons Digester 3.2 发布

Digester 3.2 发布了,Digester 是一个基于规则的XML文档解析库,主要用于XML到Java对象的映射。Struts就是用Digester来处理XML配置文件的。而且Digester还包含一个写好的RSS解析器。 该版本主...

红薯 ⋅ 2011/12/15 ⋅ 3

Digester解析xml总结

Digester用户解析xml文件形成java对象;Digester做法是: 1、先定义Digester的规则,(指明遇到xpath干什么) 2、定义好digester对象后,给一个需要解析的xml文件的输入流,开始解析,然后输...

P&H ⋅ 2014/01/02 ⋅ 0

Apache Commons Digester 1.8.1 版本发布

Digester 新发布了 1.8.1 版本,和上一个版本 1.8 比较,该版本做了小量的改进和bug的修复。 首先编译脚本中增加了 jar 的命令,直接对编译进行打包;其次所有的 Digester#parse() 方法如果传...

红薯 ⋅ 2009/01/05 ⋅ 0

XML文档解析器--Digester

Digester基于规则的XML文档解析,主要用于XML到Java对象的映射。Struts就是用Digester来处理XML配置文件的。而且Digester还包含一个写好的RSS解析器。 Maven: <dependency> <groupId>org.apa...

匿名 ⋅ 2008/09/09 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Cube、Cuboid 和 Cube Segment

1.Cube (或Data Cube),即数据立方体,是一种常用于数据分析与索引的技术;它可以对原始数据建立多维度索引。通过 Cube 对数据进行分析,可以大大加快数据的查询效率 2.Cuboid 在 Kylin 中特...

无精疯 ⋅ 36分钟前 ⋅ 0

github太慢

1:用浏览器访问 IPAddress.com or http://tool.chinaz.com 使用 IP Lookup 工具获得github.com和github.global.ssl.fastly.net域名的ip地址 2:/etc/hosts文件中添加如下格式(IP最好自己查一...

whoisliang ⋅ 37分钟前 ⋅ 0

非阻塞同步之 CAS

为解决线程安全问题,互斥同步相当于以时间换空间。多线程情况下,只有一个线程可以访问同步代码。这种同步也叫阻塞同步(Blocking Synchronization). 这种同步属于一种悲观并发策略。认为只...

长安一梦 ⋅ 48分钟前 ⋅ 0

云计算的选择悖论如何对待?

人们都希望在工作和生活中有所选择。但心理学家的调查研究表明,在多种选项中进行选择并不一定会使人们更快乐,甚至不会产生更好的决策。心理学家Barry Schwartz称之为“选择悖论”。云计算为...

linux-tao ⋅ 50分钟前 ⋅ 0

我的第一篇个人博客

虽然这是个技术博客,但是,我总是想写一些自己的东西,所有就大胆的在这里写下了第一篇非技术博客。技术博客也很久没有更新,个人原因。 以后自己打算在这里写一些非技术博客,可能个人观点...

Mrs_CoCo ⋅ 51分钟前 ⋅ 0

Redis 注册为 Windows 服务

Redis 注册为 Windows 服务 redis 注册为 windows 服务相关命令 注册服务 redis-server.exe –service-install redis.windows.conf 删除服务 redis-server –service-uninstall 启动服务 re......

Os_yxguang ⋅ 51分钟前 ⋅ 0

世界那么大,语言那么多,为什么选择Micropython,它的优势在哪?

最近国内MicroPython风靡程序界,是什么原因导致它这么火呢?是因为他功能强大,遵循Mit协议开源么? 错!因为使用它真的是太舒服了!!! Micropython的由来,这得益于Damien George这位伟大...

bodasisiter ⋅ 55分钟前 ⋅ 0

docker 清理总结

杀死所有正在运行的容器 docker kill $(docker ps -a -q) 删除所有已经停止的容器(docker rm没有加-f参数,运行中的容器不会删掉) docker rm $(docker ps -a -q) 删除所有未打 dangling 标...

vvx1024 ⋅ 今天 ⋅ 0

关于学习

以前学车的时候,教练说了这样的一句话:如果一个人坐在车上一直学,一直学,反而不如大家轮流着学。因为一个人一直学,就没有给自己留空间来反思和改进。而轮流着学的时候大家下来之后思考上...

mskk ⋅ 今天 ⋅ 0

压缩工具之gzip-bzip2-xz

win下常见压缩工具:rar zip 7z linux下常见压缩工具:zip gz bz2 xz tar.gz tar.bz2 tar.xz gzip 不支持目录压缩 gzip 1.txt #压缩。执行后1.txt消失,生成1.txt.gz压缩文件 gzip -d 1.txt....

ZHENG-JY ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部