- 浏览: 405002 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
liyuanhoa_:
...
struts2.0中struts.xml配置文件详解 -
chenmingde:
...
Velocity应用(一) -
weizhikai_ai:
第二十六,当一个线程进入一个对象的一个synchronized ...
Java常见面试题(含答案) -
Aurora_lr:
...
Spring宠物商店学习笔记(一) - -
zs911zs:
all copy from http://www.iteye ...
Mule入门文档
degister In Action (xml解析)
引言
前前后后,研究struts 的框架源代码,也有几回了,一直没有找到其解析XML 配置文件的代码 =.= !,其实是被误导了(想当然的以为它会用DOM4j或JDOM),前几天,又拿来struts的源码来跟,发现了些端倪.就仔细研究了一下,意外发现了一个很好用的解析XML的东西,即org.apache.common.digester 包.
在网上求证了一下,发现原本digester 包是和Struts一起发布的,原来只是为了解析struts-config.xml配置文件而设计的,后来发现这个包解析xml很通用,也很好用,于是,放到了commons库中.笔者小试了一下,发现果然方便,它可以直接将XML文档转换成对象,它的目标是以尽可能简单的方式把xml文件转换成对象,思想上有点类似ORM,也许以后可以起个名字叫OXM(object-xml-mapping)在本文中,也将采用OXM这个词汇.
注:本文不适合java以及struts初学者阅读,读者最好有通过SAX或DOM解析XML的经验,的经,以便更好的理解..
CH.1 digester 小窥
这一章是一个小的示例,用来像大家展示使用digester来解析xml的基本的流程.以及,使用digester来进行了xml解析是多么的简洁和简单. 本节的示例不要求你能马上读懂,在以后的章节我还会对每个类进行更详细的讲解.
好吧,让我们开始我们的digester之旅.
1.1 一个简单的xml解析示例
首先,在项目中导入commons-digester.jar包以及关联包commons-collections.jar ,commons-beanutils.jar ,commons-logging.jar.
然后,建立一个要解析的名为simple.xml的xml文档 代码如下.
Xml代码
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upcat" age="24">
<address>深 圳 市 下 梅 林 </address>
</person>
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upcat" age="24">
<address>深 圳 市 下 梅 林 </address>
</person>
接着,建立,一个同这个xml文档进行映射的pojo类.
Java代码
package com.zhengzm.prj.digester;
/**
*
* @author 7upCat
*
*/
public class Person {
private String age;
private String name;
private String address;
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
解析代码如下.
package com.zhengzm.prj.digester.simple_example;
import java.io.File;
import java.io.IOException;
import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;
public class TestDigester {
public static void main(String[] args) throws IOException, SAXException {
//创建解析对象digester
Digester digester=new Digester();
//为digester对象填加解析规则
digester.addObjectCreate("person/", Person.class);
digester.addSetProperties("person/");
digester.addBeanPropertySetter("person/address","address");
//解析xml文档返回Person对象.
Person o=(Person)digester.parse(new File("simpleXml.xml"));
//输出这个对象的值
System.out.println("the person is "+ o.getName() );
System.out.println("she/he is"+ o.getAge()+"years old");
System.out.println("she/he lives in "+o.getAddress());
}
}
package com.zhengzm.prj.digester;
/**
*
* @author 7upCat
*
*/
public class Person {
private String age;
private String name;
private String address;
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
解析代码如下.
package com.zhengzm.prj.digester.simple_example;
import java.io.File;
import java.io.IOException;
import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;
public class TestDigester {
public static void main(String[] args) throws IOException, SAXException {
//创建解析对象digester
Digester digester=new Digester();
//为digester对象填加解析规则
digester.addObjectCreate("person/", Person.class);
digester.addSetProperties("person/");
digester.addBeanPropertySetter("person/address","address");
//解析xml文档返回Person对象.
Person o=(Person)digester.parse(new File("simpleXml.xml"));
//输出这个对象的值
System.out.println("the person is "+ o.getName() );
System.out.println("she/he is"+ o.getAge()+"years old");
System.out.println("she/he lives in "+o.getAddress());
}
}
控制台输出结果如下:
the person is 7upcat
she/he is24years old
she/he lives in 深 圳 市 下 梅 林
我们看到simple.xml文档被解析后直接生成了一个Person对象,然后我们就可以直接对Person对象进行操作..
其它的xml解析方式,无论是SAX,还是DOM,都无法直接做到这点(其实digester是对SAX的简单封装),并且,Struts的配置文件是由degister来解析的, 它在实际应用中.表现也很稳定.
其实这一章可以写一下,其实的很多种解析xml的工具的代码,来分别和digester进行比较一下.但是时间实在是有限(=.= ! 要上班ING).,就不一一列举了.
下一章我们将介绍digester中的核心类Digester 和Rule 的api.以及digester的实现相制.
CH2. digester API introduction (好像名字有点大咧 )
这一章将介绍digester中的两个核心的类Digester 以及Rule并,让你明白digester的实现机制,当然,暂时不打算从源代码级别讲起,因为那个太花精力,而且,我们主要是学如何使用它(这符合XP思想? 其实可能只是作者太忙了没有时间专门去研究 ^^)
2.1 Digester类.
digester包中最重要的类就是Digester了.整个解析过程实际上就是通过调用这个对象的 java.lang.Object parse(java.io.File file) 方法来进行的,这个方法的返回值是所解析xml文档的根元素对应的对象,它还包括很多个重载版本,参数分别可以接受,InputStream,java.io.Reader,java.net.URL,等.
org.xml.sax.helpers.DefaultHandler
|
+--org.apache.commons.digester.Digester
由上面的继承结构可以看出,Digester是DefaultHandler的子类,可以推断出digester 包实际上是对SAX api的简单封装, 我们知道SAX解析XML是基于事件的,那当然,在digester中也是如此.整个解析过程将触发一系列事件,然后我们通过处理这些事件来完成我们的工作.
下面我们就使用Digester来解析一个XML文档吧.
在项目中建立person.xml如下:
Xml代码
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upCat" age="24">
<address city="深 圳 " street="梅 林 ">
</address>
<friend name="vincent"></friend>
<friend name="鱼 生 烟 "></friend>
</person>
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upCat" age="24">
<address city="深 圳 " street="梅 林 ">
</address>
<friend name="vincent"></friend>
<friend name="鱼 生 烟 "></friend>
</person>
从这个XML文件中可以看出,对于每个person 都会有 name和age两个属性,并且,每个person节点都会有多个friends子节点,有一个address子节点.
我们的目标是,通过解析上面的XML文件,得到一个Person对象,并且这个对象中包含多个Friend对象的集合,一个Address对象.
接着,建立需要做 OXM的 pojo (plain old java object)类(^^相信,如果读者有用过hibernate的经验应该可以很容易理解).
注: pojo 就是符合javabean规范的普通的java对象.(含setter getter)
Person 类.
Java代码
package com.zhengzm.prj.digester.ch2.pojo;
import java.util.Vector;
/**
* 每 一 个 person中 包 含 了 ,这 个 人 的 名 字 ,年 龄 ,居 住 地 址 address对 象 ,朋 友 的 集 合 friends
*
* @author 7upCat
*
*/
public class Person {
private String name;
private String age;
public Address address;
/**
* friends 对 象 的 集 合 .
*/
public Vector<Friend> friends = new Vector<Friend>();
public void addFriend(Friend f) {
friends.addElement(f);
}
public Vector<Friend> getFriends() {
return friends;
}
public void setFriends(Vector<Friend> friends) {
this.friends = friends;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("这 个 家 伙 名 叫 " + this.name + "今 年 " + this.age + "岁 了 ");
sb.append("\n");
sb.append("他 /居 住 在 : " + address.toString());
sb.append("\n");
sb.append("他 /她 的 朋 友 是 :");
for (Friend friend : friends) {
sb.append(friend.getName());
sb.append(" ");
}
return sb.toString();
}
}
package com.zhengzm.prj.digester.ch2.pojo;
import java.util.Vector;
/**
* 每 一 个 person中 包 含 了 ,这 个 人 的 名 字 ,年 龄 ,居 住 地 址 address对 象 ,朋 友 的 集 合 friends
*
* @author 7upCat
*
*/
public class Person {
private String name;
private String age;
public Address address;
/**
* friends 对 象 的 集 合 .
*/
public Vector<Friend> friends = new Vector<Friend>();
public void addFriend(Friend f) {
friends.addElement(f);
}
public Vector<Friend> getFriends() {
return friends;
}
public void setFriends(Vector<Friend> friends) {
this.friends = friends;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("这 个 家 伙 名 叫 " + this.name + "今 年 " + this.age + "岁 了 ");
sb.append("\n");
sb.append("他 /居 住 在 : " + address.toString());
sb.append("\n");
sb.append("他 /她 的 朋 友 是 :");
for (Friend friend : friends) {
sb.append(friend.getName());
sb.append(" ");
}
return sb.toString();
}
}
Friend 类
Java代码
package com.zhengzm.prj.digester.ch2.pojo;
/**
*
* @author 7upCat
*
*/
public class Friend {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
package com.zhengzm.prj.digester.ch2.pojo;
/**
*
* @author 7upCat
*
*/
public class Friend {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
Address 类
Java代码
package com.zhengzm.prj.digester.ch2.pojo;
/**
*
* a address object contaions the name of the city and the name of the street
*
* @author 7upCat
*
*/
public class Address {
private String city;
private String street;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public String toString() {
return city+"市 ,"+street+"\n";
}
}
package com.zhengzm.prj.digester.ch2.pojo;
/**
*
* a address object contaions the name of the city and the name of the street
*
* @author 7upCat
*
*/
public class Address {
private String city;
private String street;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public String toString() {
return city+"市 ,"+street+"\n";
}
}
准备工作终于完成,解析的代码如下所示
Java代码
Digester digester=new Digester();
Person person=(Person)digester.parse(new File("person.xml"));
System.out.println(person);
Digester digester=new Digester();
Person person=(Person)digester.parse(new File("person.xml"));
System.out.println(person);
运行,结果为null 为什么呢? 结果不应该是Person对象吗? 请读者回忆一下我们刚才做过的事情.
1.写了一个person.xml的xml文件.
2.写了一组和person.xml做映射的pojo.
3.解析xml文档.
: ) 似乎少了点什么吧.大家不妨想想做ORM的时候, 我们做过的步骤.
1.建立数据库表.
2.写一组同这些数据库表做映射的pojo.
3.添写,将这些pojo同数据库表关联起来的配置文件(可能是xml,也可能是properties文档).
4.对pojo对象进行数据库操作.
细心的读者一定发现了,在我们解析xml文档的时候少了哪一步骤, 我们并没有把xml文件,同pojo以某种形式关联起来,于是,理解应当我们解析的时候并没有产生相应的Object ..
可在digester中xml文档,同pojo 是如何关联起来的呢? 在digester中实际上是通过监听器来实现这个的,下面一节我们将介绍Rule类,以及它的子类.并为Digester对象添加监听器.
2.2 Rule类以及digester世界中的pattern.
Rule是digester世界中的监听器的抽象基类, 由于,Rule是抽象类,不能被实例化,所以你要使用Rule的时候必需继承它,并覆盖相应的方法.Digester则是被监听对象,如果你不为你的Digester对象,来注册监听,那么解析xml文档中的所有事件都将全部被忽略.
Rule类一共声明了3个方法,如果,每个方法都有一个namespace 敏感的重载版本.(注一)
void begin(Attributes attributes)
解析时遇到符合pattern匹配规则的文档的xml的节点时被调用.
void body(String text)
解析时遇到符合pattern匹配规则的文档的xml的节点的值时被调用,并将这个值做为参数传递给方法.如果这个节点没有值,这个方法也会被调用,并将 null做为调用参数
void end()
解析时遇到符合pattern匹配规则的文档的xml的节点结束时被调用.
注一: 所谓的namespace敏感的重载版本实际上说的意思是,当Digester对象通过, setNamespaceAware(boolean namespaceAware) 方法设置为true的时候,那么,将会调用.重载版本的方法,而不是上面的3个方法.
例如下面这个SimpleRule就是覆盖了Rule的begin方法, 并简单向控制台输出信息.
Java代码
package com.zhengzm.prj.digester.simple_example;
import org.apache.commons.digester.Rule;
import org.xml.sax.Attributes;
/***
* 一 个 简 单 的 Rule实 现 ,仅 向 控 制 台 输 出 一 句 话 /
* @author 7upCat
*
*/
public class SimpleRule extends Rule {
@Override
public void begin(Attributes attributes) throws Exception {
System.out.println(" begin countered");
}
@Override
public void body(String namespace, String name, String text)
throws Exception {
System.out.println("body endcountered ");
}
@Override
public void end() throws Exception {
System.out.println("end countered");
}
}
package com.zhengzm.prj.digester.simple_example;
import org.apache.commons.digester.Rule;
import org.xml.sax.Attributes;
/***
* 一 个 简 单 的 Rule实 现 ,仅 向 控 制 台 输 出 一 句 话 /
* @author 7upCat
*
*/
public class SimpleRule extends Rule {
@Override
public void begin(Attributes attributes) throws Exception {
System.out.println(" begin countered");
}
@Override
public void body(String namespace, String name, String text)
throws Exception {
System.out.println("body endcountered ");
}
@Override
public void end() throws Exception {
System.out.println("end countered");
}
}
我们通过, Digester对象的 addRule(java.lang.String pattern, Rule rule)方法,来为它注册监听器. 参数pattern是匹配的规则.在digester中,是以嵌套的标签名称以“/“相连接来做为匹配规则的. 以2,1中的person.xml文件为例.
Xml代码
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upCat" age="24">
<address city="深圳" street="梅林">
</address>
<friend name="vincent" age="24" ></friend>
<friend name="鱼生烟" age=“23“></friend>
</person>
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upCat" age="24">
<address city="深圳" street="梅林">
</address>
<friend name="vincent" age="24" ></friend>
<friend name="鱼生烟" age=“23“></friend>
</person>
"person/“ 将同<person>标签匹配
"person/address/“ 同<address>标签匹配
"person/friend/“ 同<friend>标签匹配
我们现在先把这个SimpleRule注册给Degister 对象,然后再来解析一下,person.xml看看会出现什么情况呢?
Java代码
Digester digester=new Digester();
digester.addRule("person/",new SimpleRule() );
Person o=(Person)digester.parse(new File("person.xml"));
System.out.println("the person is "+ o );
Digester digester=new Digester();
digester.addRule("person/",new SimpleRule() );
Person o=(Person)digester.parse(new File("person.xml"));
System.out.println("the person is "+ o );
输出结果是:
begin countered
body endcountered
end countered
the person is null
我们看到, SimpleRule中的方法均被调用了.然而,我们的Person对象依然没有被创建.不要灰心,现在你已经明白了,digester包实现的基本原理, Degister类通过继承org.xml.sax.helpers.DefaultHandle来监听使用SAX来解析XML文档时发生的事件,并对事件产生的数据进行了包装,然后调用注册在Degister中相匹配的Rule的子类的方法.对数据进行进一步封装.
下一章,我们将介绍一些Degister中一些十分有用的方法,和一些由digester包提供好的Rule的实现 .
引言
前前后后,研究struts 的框架源代码,也有几回了,一直没有找到其解析XML 配置文件的代码 =.= !,其实是被误导了(想当然的以为它会用DOM4j或JDOM),前几天,又拿来struts的源码来跟,发现了些端倪.就仔细研究了一下,意外发现了一个很好用的解析XML的东西,即org.apache.common.digester 包.
在网上求证了一下,发现原本digester 包是和Struts一起发布的,原来只是为了解析struts-config.xml配置文件而设计的,后来发现这个包解析xml很通用,也很好用,于是,放到了commons库中.笔者小试了一下,发现果然方便,它可以直接将XML文档转换成对象,它的目标是以尽可能简单的方式把xml文件转换成对象,思想上有点类似ORM,也许以后可以起个名字叫OXM(object-xml-mapping)在本文中,也将采用OXM这个词汇.
注:本文不适合java以及struts初学者阅读,读者最好有通过SAX或DOM解析XML的经验,的经,以便更好的理解..
CH.1 digester 小窥
这一章是一个小的示例,用来像大家展示使用digester来解析xml的基本的流程.以及,使用digester来进行了xml解析是多么的简洁和简单. 本节的示例不要求你能马上读懂,在以后的章节我还会对每个类进行更详细的讲解.
好吧,让我们开始我们的digester之旅.
1.1 一个简单的xml解析示例
首先,在项目中导入commons-digester.jar包以及关联包commons-collections.jar ,commons-beanutils.jar ,commons-logging.jar.
然后,建立一个要解析的名为simple.xml的xml文档 代码如下.
Xml代码
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upcat" age="24">
<address>深 圳 市 下 梅 林 </address>
</person>
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upcat" age="24">
<address>深 圳 市 下 梅 林 </address>
</person>
接着,建立,一个同这个xml文档进行映射的pojo类.
Java代码
package com.zhengzm.prj.digester;
/**
*
* @author 7upCat
*
*/
public class Person {
private String age;
private String name;
private String address;
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
解析代码如下.
package com.zhengzm.prj.digester.simple_example;
import java.io.File;
import java.io.IOException;
import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;
public class TestDigester {
public static void main(String[] args) throws IOException, SAXException {
//创建解析对象digester
Digester digester=new Digester();
//为digester对象填加解析规则
digester.addObjectCreate("person/", Person.class);
digester.addSetProperties("person/");
digester.addBeanPropertySetter("person/address","address");
//解析xml文档返回Person对象.
Person o=(Person)digester.parse(new File("simpleXml.xml"));
//输出这个对象的值
System.out.println("the person is "+ o.getName() );
System.out.println("she/he is"+ o.getAge()+"years old");
System.out.println("she/he lives in "+o.getAddress());
}
}
package com.zhengzm.prj.digester;
/**
*
* @author 7upCat
*
*/
public class Person {
private String age;
private String name;
private String address;
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
解析代码如下.
package com.zhengzm.prj.digester.simple_example;
import java.io.File;
import java.io.IOException;
import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;
public class TestDigester {
public static void main(String[] args) throws IOException, SAXException {
//创建解析对象digester
Digester digester=new Digester();
//为digester对象填加解析规则
digester.addObjectCreate("person/", Person.class);
digester.addSetProperties("person/");
digester.addBeanPropertySetter("person/address","address");
//解析xml文档返回Person对象.
Person o=(Person)digester.parse(new File("simpleXml.xml"));
//输出这个对象的值
System.out.println("the person is "+ o.getName() );
System.out.println("she/he is"+ o.getAge()+"years old");
System.out.println("she/he lives in "+o.getAddress());
}
}
控制台输出结果如下:
the person is 7upcat
she/he is24years old
she/he lives in 深 圳 市 下 梅 林
我们看到simple.xml文档被解析后直接生成了一个Person对象,然后我们就可以直接对Person对象进行操作..
其它的xml解析方式,无论是SAX,还是DOM,都无法直接做到这点(其实digester是对SAX的简单封装),并且,Struts的配置文件是由degister来解析的, 它在实际应用中.表现也很稳定.
其实这一章可以写一下,其实的很多种解析xml的工具的代码,来分别和digester进行比较一下.但是时间实在是有限(=.= ! 要上班ING).,就不一一列举了.
下一章我们将介绍digester中的核心类Digester 和Rule 的api.以及digester的实现相制.
CH2. digester API introduction (好像名字有点大咧 )
这一章将介绍digester中的两个核心的类Digester 以及Rule并,让你明白digester的实现机制,当然,暂时不打算从源代码级别讲起,因为那个太花精力,而且,我们主要是学如何使用它(这符合XP思想? 其实可能只是作者太忙了没有时间专门去研究 ^^)
2.1 Digester类.
digester包中最重要的类就是Digester了.整个解析过程实际上就是通过调用这个对象的 java.lang.Object parse(java.io.File file) 方法来进行的,这个方法的返回值是所解析xml文档的根元素对应的对象,它还包括很多个重载版本,参数分别可以接受,InputStream,java.io.Reader,java.net.URL,等.
org.xml.sax.helpers.DefaultHandler
|
+--org.apache.commons.digester.Digester
由上面的继承结构可以看出,Digester是DefaultHandler的子类,可以推断出digester 包实际上是对SAX api的简单封装, 我们知道SAX解析XML是基于事件的,那当然,在digester中也是如此.整个解析过程将触发一系列事件,然后我们通过处理这些事件来完成我们的工作.
下面我们就使用Digester来解析一个XML文档吧.
在项目中建立person.xml如下:
Xml代码
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upCat" age="24">
<address city="深 圳 " street="梅 林 ">
</address>
<friend name="vincent"></friend>
<friend name="鱼 生 烟 "></friend>
</person>
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upCat" age="24">
<address city="深 圳 " street="梅 林 ">
</address>
<friend name="vincent"></friend>
<friend name="鱼 生 烟 "></friend>
</person>
从这个XML文件中可以看出,对于每个person 都会有 name和age两个属性,并且,每个person节点都会有多个friends子节点,有一个address子节点.
我们的目标是,通过解析上面的XML文件,得到一个Person对象,并且这个对象中包含多个Friend对象的集合,一个Address对象.
接着,建立需要做 OXM的 pojo (plain old java object)类(^^相信,如果读者有用过hibernate的经验应该可以很容易理解).
注: pojo 就是符合javabean规范的普通的java对象.(含setter getter)
Person 类.
Java代码
package com.zhengzm.prj.digester.ch2.pojo;
import java.util.Vector;
/**
* 每 一 个 person中 包 含 了 ,这 个 人 的 名 字 ,年 龄 ,居 住 地 址 address对 象 ,朋 友 的 集 合 friends
*
* @author 7upCat
*
*/
public class Person {
private String name;
private String age;
public Address address;
/**
* friends 对 象 的 集 合 .
*/
public Vector<Friend> friends = new Vector<Friend>();
public void addFriend(Friend f) {
friends.addElement(f);
}
public Vector<Friend> getFriends() {
return friends;
}
public void setFriends(Vector<Friend> friends) {
this.friends = friends;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("这 个 家 伙 名 叫 " + this.name + "今 年 " + this.age + "岁 了 ");
sb.append("\n");
sb.append("他 /居 住 在 : " + address.toString());
sb.append("\n");
sb.append("他 /她 的 朋 友 是 :");
for (Friend friend : friends) {
sb.append(friend.getName());
sb.append(" ");
}
return sb.toString();
}
}
package com.zhengzm.prj.digester.ch2.pojo;
import java.util.Vector;
/**
* 每 一 个 person中 包 含 了 ,这 个 人 的 名 字 ,年 龄 ,居 住 地 址 address对 象 ,朋 友 的 集 合 friends
*
* @author 7upCat
*
*/
public class Person {
private String name;
private String age;
public Address address;
/**
* friends 对 象 的 集 合 .
*/
public Vector<Friend> friends = new Vector<Friend>();
public void addFriend(Friend f) {
friends.addElement(f);
}
public Vector<Friend> getFriends() {
return friends;
}
public void setFriends(Vector<Friend> friends) {
this.friends = friends;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("这 个 家 伙 名 叫 " + this.name + "今 年 " + this.age + "岁 了 ");
sb.append("\n");
sb.append("他 /居 住 在 : " + address.toString());
sb.append("\n");
sb.append("他 /她 的 朋 友 是 :");
for (Friend friend : friends) {
sb.append(friend.getName());
sb.append(" ");
}
return sb.toString();
}
}
Friend 类
Java代码
package com.zhengzm.prj.digester.ch2.pojo;
/**
*
* @author 7upCat
*
*/
public class Friend {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
package com.zhengzm.prj.digester.ch2.pojo;
/**
*
* @author 7upCat
*
*/
public class Friend {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
Address 类
Java代码
package com.zhengzm.prj.digester.ch2.pojo;
/**
*
* a address object contaions the name of the city and the name of the street
*
* @author 7upCat
*
*/
public class Address {
private String city;
private String street;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public String toString() {
return city+"市 ,"+street+"\n";
}
}
package com.zhengzm.prj.digester.ch2.pojo;
/**
*
* a address object contaions the name of the city and the name of the street
*
* @author 7upCat
*
*/
public class Address {
private String city;
private String street;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public String toString() {
return city+"市 ,"+street+"\n";
}
}
准备工作终于完成,解析的代码如下所示
Java代码
Digester digester=new Digester();
Person person=(Person)digester.parse(new File("person.xml"));
System.out.println(person);
Digester digester=new Digester();
Person person=(Person)digester.parse(new File("person.xml"));
System.out.println(person);
运行,结果为null 为什么呢? 结果不应该是Person对象吗? 请读者回忆一下我们刚才做过的事情.
1.写了一个person.xml的xml文件.
2.写了一组和person.xml做映射的pojo.
3.解析xml文档.
: ) 似乎少了点什么吧.大家不妨想想做ORM的时候, 我们做过的步骤.
1.建立数据库表.
2.写一组同这些数据库表做映射的pojo.
3.添写,将这些pojo同数据库表关联起来的配置文件(可能是xml,也可能是properties文档).
4.对pojo对象进行数据库操作.
细心的读者一定发现了,在我们解析xml文档的时候少了哪一步骤, 我们并没有把xml文件,同pojo以某种形式关联起来,于是,理解应当我们解析的时候并没有产生相应的Object ..
可在digester中xml文档,同pojo 是如何关联起来的呢? 在digester中实际上是通过监听器来实现这个的,下面一节我们将介绍Rule类,以及它的子类.并为Digester对象添加监听器.
2.2 Rule类以及digester世界中的pattern.
Rule是digester世界中的监听器的抽象基类, 由于,Rule是抽象类,不能被实例化,所以你要使用Rule的时候必需继承它,并覆盖相应的方法.Digester则是被监听对象,如果你不为你的Digester对象,来注册监听,那么解析xml文档中的所有事件都将全部被忽略.
Rule类一共声明了3个方法,如果,每个方法都有一个namespace 敏感的重载版本.(注一)
void begin(Attributes attributes)
解析时遇到符合pattern匹配规则的文档的xml的节点时被调用.
void body(String text)
解析时遇到符合pattern匹配规则的文档的xml的节点的值时被调用,并将这个值做为参数传递给方法.如果这个节点没有值,这个方法也会被调用,并将 null做为调用参数
void end()
解析时遇到符合pattern匹配规则的文档的xml的节点结束时被调用.
注一: 所谓的namespace敏感的重载版本实际上说的意思是,当Digester对象通过, setNamespaceAware(boolean namespaceAware) 方法设置为true的时候,那么,将会调用.重载版本的方法,而不是上面的3个方法.
例如下面这个SimpleRule就是覆盖了Rule的begin方法, 并简单向控制台输出信息.
Java代码
package com.zhengzm.prj.digester.simple_example;
import org.apache.commons.digester.Rule;
import org.xml.sax.Attributes;
/***
* 一 个 简 单 的 Rule实 现 ,仅 向 控 制 台 输 出 一 句 话 /
* @author 7upCat
*
*/
public class SimpleRule extends Rule {
@Override
public void begin(Attributes attributes) throws Exception {
System.out.println(" begin countered");
}
@Override
public void body(String namespace, String name, String text)
throws Exception {
System.out.println("body endcountered ");
}
@Override
public void end() throws Exception {
System.out.println("end countered");
}
}
package com.zhengzm.prj.digester.simple_example;
import org.apache.commons.digester.Rule;
import org.xml.sax.Attributes;
/***
* 一 个 简 单 的 Rule实 现 ,仅 向 控 制 台 输 出 一 句 话 /
* @author 7upCat
*
*/
public class SimpleRule extends Rule {
@Override
public void begin(Attributes attributes) throws Exception {
System.out.println(" begin countered");
}
@Override
public void body(String namespace, String name, String text)
throws Exception {
System.out.println("body endcountered ");
}
@Override
public void end() throws Exception {
System.out.println("end countered");
}
}
我们通过, Digester对象的 addRule(java.lang.String pattern, Rule rule)方法,来为它注册监听器. 参数pattern是匹配的规则.在digester中,是以嵌套的标签名称以“/“相连接来做为匹配规则的. 以2,1中的person.xml文件为例.
Xml代码
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upCat" age="24">
<address city="深圳" street="梅林">
</address>
<friend name="vincent" age="24" ></friend>
<friend name="鱼生烟" age=“23“></friend>
</person>
<?xml version="1.0" encoding="UTF-8"?>
<person name="7upCat" age="24">
<address city="深圳" street="梅林">
</address>
<friend name="vincent" age="24" ></friend>
<friend name="鱼生烟" age=“23“></friend>
</person>
"person/“ 将同<person>标签匹配
"person/address/“ 同<address>标签匹配
"person/friend/“ 同<friend>标签匹配
我们现在先把这个SimpleRule注册给Degister 对象,然后再来解析一下,person.xml看看会出现什么情况呢?
Java代码
Digester digester=new Digester();
digester.addRule("person/",new SimpleRule() );
Person o=(Person)digester.parse(new File("person.xml"));
System.out.println("the person is "+ o );
Digester digester=new Digester();
digester.addRule("person/",new SimpleRule() );
Person o=(Person)digester.parse(new File("person.xml"));
System.out.println("the person is "+ o );
输出结果是:
begin countered
body endcountered
end countered
the person is null
我们看到, SimpleRule中的方法均被调用了.然而,我们的Person对象依然没有被创建.不要灰心,现在你已经明白了,digester包实现的基本原理, Degister类通过继承org.xml.sax.helpers.DefaultHandle来监听使用SAX来解析XML文档时发生的事件,并对事件产生的数据进行了包装,然后调用注册在Degister中相匹配的Rule的子类的方法.对数据进行进一步封装.
下一章,我们将介绍一些Degister中一些十分有用的方法,和一些由digester包提供好的Rule的实现 .
发表评论
-
深入考察 JAXB,第 2 部分
2008-12-22 11:29 1423回顾 本专栏的 第一篇中,您已经了解一些重要的术语: 编组和 ... -
考察 JAXB,第 1 部分
2008-12-22 11:28 1497简述 不过在展开 JAXB 的讨论之前,我要简要地回顾一下 ... -
jaxb接口学习实践
2008-12-22 11:26 1671jdk带了支持jaxb的包,为javax.xml.bind.* ... -
jaxb 简介
2008-12-22 10:23 1123JavaTM Architecture for XML B ... -
XML解析技术
2008-11-26 10:37 1207Java中四种XML解析技术 ...
相关推荐
Dom4j解析struts2框架的struts.xml,自定义struts框架需要解析配置文件
自定义类似struts的mvc框架,有struts1和struts2的共同特点
Struts1.0和1.1差别很大,主要有两点:Struts1.1中引用了很多apache其他项目的类包,如:xml解析、日志、验证等,因此struts1.1的包结构与1.0完全不同。在struts1.1环境下,一个webapp要成功运行,除了struts.jar外...
此项目是为了更深入的理解MVC模式以及Struts的工作流程而开发的,运用了第三方commons组件, commons-digester来解析xml文件,把配置信息全部封装成类,然后运用MVC的思想去做相应的操作.
主要介绍了struts2 validation.xml 验证规则代码解析,具有一定借鉴价值,需要的朋友可以参考下
第一部分 Struts的优势 第二部分 Struts框架与MVC 第三部分 Struts工作流程 第四部分 Struts-config.xml的配置文件解析 第五部分 Struts中错误处理 第六部分 Struts实例操作
使用servlet模拟struts1的工作原理,解析xml,处理请求,自动封装数据
配置常量,可以改变Struts 2框架的一些行为 name属性表示常量名称,value属性表示常量值 package元素: 包的作用:简化维护工作,提高重用性 包可以“继承”已定义的包,并可以添加自己包的配置 name属性为必须去且...
struts2学习教程包括:第一个Struts2程序,处理一个form多个submit,struts.xml常用配置解析,使用validate方法验证数据,使用Validation框架验证数据,在Action类中获得HttpServletResponse对象的四种方法,上传...
用sevrlet模拟Struts2的简单功能。从拦截请求、解析自定义xml数据文件以及动态生成action的代理去执行目标方法,并实现了简单的日志拦截【interceptor】
使用Struts的Action来对数据库进行增、删、改、查四项操作 <br/>1、数据库MySQL,创建数据库 Pagination MySQL.sql用来创建表结构 <br/>连接方式有两种,一种直接JDBC,一种通过连接池,代码中有说明...
第一部分 Struts的优势 第二部分 Struts框架与MVC 第三部分 Struts工作流程 第四部分 Struts-config.xml的配置文件解析 第五部分 Struts中错误处理 第六部分 Struts实例操作
讲解如何用EFS前台框架实现和后台数据交换 原创教程 欢迎交流
12.6.15 编写Struts的配置文件struts-config.xml 12.6.16 编写Spring和Hibernate的配置文件spring-config.xml 12.6.17 编写web.xml 12.6.18 验证示例 12.7 小结 第四篇 J2EE项目案例精选 第十三章 网上调查系统 13.1...
一个请求在Struts2框架中的处理大概分为以下几个步骤: 1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求 2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选...
12.6.15 编写Struts的配置文件struts-config.xml 12.6.16 编写Spring和Hibernate的配置文件spring-config.xml 12.6.17 编写web.xml 12.6.18 验证示例 12.7 小结 第四篇 J2EE项目案例精选 第十三章 网上调查系统 13.1...
与使用传统的XML格式或者JSON格式相比,新的树结构信息表示法将占用更少的存储空间,获得更高的解析效率。新框架的请求处理流程借鉴了JSF的请求生命周期,但对它进行了改造,从而简化了流程。本文还将Java反射机制与...
工具详尽:包括JDK、Tomcat、Eclipse、MySQL、Log4j、Ant、JUnit、CVS、解析XML文件等; 由浅入深:每章从简单示例入手,最后给出一个详细示例加深理解; 实战性强:书中提供了大量典型的应用案例,实战性很强; ...
12.6.15 编写Struts的配置文件struts-config.xml 12.6.16 编写Spring和Hibernate的配置文件spring-config.xml 12.6.17 编写web.xml 12.6.18 验证示例 12.7 小结 第四篇 J2EE项目案例精选 第十三章 网上调查系统 13.1...
append 标签: 这些append标签需要两个或两个以上的列表作为参数,并追加它们放在一起,如下图所示: 如果有两个列表A和B的值A1,A2和B1,