- 浏览: 413302 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
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 1480回顾 本专栏的 第一篇中,您已经了解一些重要的术语: 编组和 ... -
考察 JAXB,第 1 部分
2008-12-22 11:28 1525简述 不过在展开 JAXB 的讨论之前,我要简要地回顾一下 ... -
jaxb接口学习实践
2008-12-22 11:26 1707jdk带了支持jaxb的包,为javax.xml.bind.* ... -
jaxb 简介
2008-12-22 10:23 1144JavaTM Architecture for XML B ... -
XML解析技术
2008-11-26 10:37 1235Java中四种XML解析技术 ...
相关推荐
### Struts框架中struts-config.xml文件配置详解 #### 一、引言 在Java Web开发领域,Struts是一个非常重要的MVC(Model-View-Controller)框架,它极大地简化了Web应用程序的开发过程。而在Struts框架中,`struts...
本篇文章将深入探讨如何使用Dom4j这个XML处理库来解析`struts.xml`,以便自定义和配置Struts2框架。 Dom4j是一个灵活且功能丰富的Java库,专门用于处理XML文档。它提供了全面的API,可以方便地读取、写入、修改和...
为了更好地理解和应用Struts框架,本文将深入解析这些关键知识点。 ### Struts框架概述 Struts是一个开源的Web应用程序框架,属于MVC(Model-View-Controller)模式的一种实现。它主要用于Java EE平台上的Web开发...
在这个“仿struts框架的自制代码”中,我们可以看到作者尝试模仿Struts的核心功能,并结合了多种技术,如DOM4J、JNDI以及处理Excel的代码。 1. **Servlet**: Servlet是Java服务器端的API,用于扩展服务器的功能。在...
Struts.xml配置文件是Struts2框架的核心配置文件,它定义了应用的行为和结构。本文主要解析了其中两个重要的配置元素:`<include>`标签和Action的别名。 首先,我们来看 `<include>` 标签的使用。当Struts2的应用中...
Struts框架是一个基于MVC(模型-视图-控制器)设计模式的Java Web应用程序框架,由Apache软件基金会的Struts项目开发。它旨在提供一种结构化的、可维护性高的开发方式,以帮助开发者构建Web应用。以下是Struts框架的...
将这些JAR包拷贝到`WEB-INF/lib`目录下,可以确保Struts框架的正常运行,同时这些库也支持其他相关的功能,如XML解析、数据验证、日志记录和文件上传等。在实际开发中,还需要根据项目需求添加其他必要的库,如...
Struts2 jQuery XML 是一个基于Java的Web开发框架的组合,它将Apache Struts2的MVC架构与jQuery库结合,提供了丰富的用户界面组件和更流畅的AJAX交互。Struts2是一个强大的、灵活的MVC框架,而jQuery则简化了...
10. **ActionServlet**:Struts框架的入口点是ActionServlet,它是Servlet的子类,负责解析请求,调用Action,处理结果等。 11. ** strut2-struts1-plugin**:如果项目中还包含Struts1的遗留代码,可以通过Struts2...
在Struts2中,配置文件`struts.xml`扮演着核心角色,它定义了动作(Action)、包(Package)和结果(Result)等关键组件的行为。为了方便地解析和处理这些配置,开发者常常会创建自定义的包装类(Wrapper Class),...
在整合老项目与Struts2框架的过程中,可能会遇到XML解析相关的错误,这通常是由于Struts2在启动时尝试使用不兼容或不适合的XML解析器导致的。本文将深入探讨这个问题,提供解决方案,并介绍如何避免此类问题。 错误...
Struts框架是Java Web开发中常用的一个开源MVC框架,由Apache软件基金会维护。它提供了一种组织应用程序的方式,使得开发者能够将业务逻辑、控制流程和表现层分离,从而提高代码的可重用性和可维护性。在这个"学生...
在开发过程中,我们经常会遇到与`struts.xml`配置文件相关的错误,这是由于XML解析问题或者DTD(文档类型定义)引用的问题引起的。`struts.xml`是Struts2框架的核心配置文件,它定义了动作、结果、拦截器等关键组件...
Struts框架是Java Web开发中常用的一个开源MVC框架,由Apache软件基金会维护...以上是对Struts框架中文件上传下载功能的详细解析,希望对你理解这一主题有所帮助。如需进一步讨论,可以加入指定的QQ群或通过邮件联系。
Struts2作为一款强大的MVC框架,其核心配置文件`struts.xml`在应用程序中扮演着至关重要的角色。本文将深入解析`struts.xml`中的Action配置,帮助开发者更好地理解和运用这一关键组件。 首先,Action配置是Struts2...
Struts框架通过解析这些请求,提供了一种处理文件上传的便捷方式。 在Struts框架中,文件上传主要依赖于两个关键组件:`Commons FileUpload`库和`Struts2上传插件`。`Commons FileUpload`是Apache的一个子项目,...
在IT行业中,构建一个自定义的类似于Struts的MVC框架是一项挑战性的任务,它涉及到对Web开发模式的深入理解,以及对Java、JSP、XML解析等技术的熟练运用。Struts作为Java EE领域中著名的MVC框架,其设计思想和实现...
在Java Web开发领域,Struts框架一直是构建MVC架构应用的重要工具之一。而`struts-config.xml`配置文件则是Struts应用的核心配置文件,它负责管理Struts应用中的各种组件配置。本文将详细介绍`struts-config.xml`...
4. **ActionServlet**:这是Struts框架的核心Servlet,负责解析请求,根据配置文件中的映射信息调用相应的Action。 5. **Tiles**:Tiles是Struts的一个扩展,它提供了更灵活的页面布局和组合功能,可以将页面拆分成...