之前的工作经常用到struts1框架,但是说实话,里面的具体实现确实不甚清楚,于是乎今天在看ActionServlet初始化资源的时候整理了一下Digester的使用。要系统的理解Digester可能还得在SAX上费些时间。我这里只是把几个简单的应用罗列一下,希望对自己和别人都有所帮助。
Digester是基于SAX之上的一种简化XML解析逻辑的一个开源项目,来源于 Strut1的项目。
Digester在处理xml文件的时候主要分成以下几步:
实例化一个Digester实例,为digester添加一些属性(如nameSpace,validate等),接着是为digester添加rule规则,最后将目标xml文件转换为InputStream给digester解析。
Digester中各种各样的rule是Digester之所以如此灵活运用的根本。
在介绍解析的例子之前还有一点需要声明,Digester在解析对象是是利用栈(Stack)原理来处理方法的作用对象的。
接着我们从2个例子来介绍,2中典型的解析XML的方法(前一种是针对InnerText类型的XML,后一种是针对property格式的XML)。
先来看第一种解析:
ServletBean.java
test1.xml
处理方法:
根据最后的处理方法我们来做一番分析:
1.当碰到pattern为web-app/servlet时候,创建一个ServletBean实例压如栈中。
2.当碰到pattern为web-app/servlet-name的时候,寻找当前占类引用(ServletBean引用)的setServletName方法,该方法参数个数为0.
3.当碰到pattern为web-app/servlet/init-param的时候,寻找当前栈引用并调用其方法setParamInfo该方法有2个参数。
4.将符合web-app/servlet/init-param/param-name的pattern元素内容作为第0个参数设置到setParamInfo方法中。
5.最后将xml文件以InputStream的形式送给digester解析。处理完毕后返回栈顶类的引用(ServletBean),进而可以获得当中的内容。
再来看第2种解析:
Foo.java
Bar.java
test2.xml
处理方法:
我们来对第2中解析XML的方法做下分析:
1.遇到pattern匹配foo时候创建一个Foo对象,并压入栈中。
2.定义foo下属性到Foo对象成员变量的映射。
3.当遇到pattern为foo/bar的时候。创建一个Bar元素,再将Bar元素压入堆栈中。
4.定义bar下属性到Bar对象成员变量的映射。
5.完成一个Bar映射后,从栈里弹出Bar引用,这时栈的peek值为Foo的引用,于是addSetNext方法告诉我们,调用Foo对象引用的addBar元素,参数为Bar类的引用。
6.当把所有的映射处理完毕之后再弹出Foo对象。
7.digester处理完成后返回最外层的Foo对象的实例引用。
以上介绍了2种解析XML的方法,然后还更大家分享一种方法,就是digester的addRuleSet(RuleSet)方法,这个方法的参数是一个需要继承RuleSetBase的自定义类。并且要自己实现addRuleInstances(digester)方法,将digester的具体逻辑写在该回调方法里面即可。
至于命名空间的设置以及验证,在本文中不做详细解释。
希望以上总结的内容对大家有所帮助。
参考资料:http://commons.apache.org/digester/commons-digester-1.8/docs/api/org/apache/commons/digester/package-summary.html