最近打算看一下tomcat的源码,当读到Catalina的load方法时,发现server.xml文件的解析及各种容器的实例化都是通过Digester来实现的,为了更好的了解tomcat中容器的结构,先了解一下Digester的使用方法。
Digester主要是解析xml,根据规则做对象的实例化、对象属性赋值及方法的调用。
下面是一个学校、学院及学生关系的xml
<School name="化工大学" address="北三环东路">
<College name="信息学院">
<Student name="张三" sex="1"/>
<Student name="李四" sex="0"/>
</College>
<College name="生命学院">
<Student name="王五" sex="1"/>
<Student name="赵六" sex="0"/>
</College>
</School>
解析xml的java代码
package javax.zyl.digester;
import org.apache.tomcat.util.digester.Digester;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
/**
* Date: 2016/12/30 Time: 下午10:34
*/
public class DigesterTest {
public static void main(String[] args) throws IOException, SAXException {
new DigesterTest().testInitSchoolInfo();
}
/**
* 学校
*/
private School school;
private void testInitSchoolInfo() throws IOException, SAXException {
Digester digester = new Digester();
//创建一个对象:如果xml的School节点中存在属性classNameInXml,则生成属性classNameInXml对应的实例
//如果xml的School节点中不存在属性classNameInXml,则生成javax.zyl.digester.School实例
digester.addObjectCreate("School","javax.zyl.digester.School","classNameInXml");
//为上一行代码生成的实例,设置属性值(匹配xml中school节点的属性名称和实例的字段名称)
digester.addSetProperties("School");
//调用digester中root的setSchool方法,root会在解析xml之前进行设置
digester.addSetNext("School","setSchool","javax.zyl.digester.School");
//同School对象的创建
digester.addObjectCreate("School/College","javax.zyl.digester.College","classNameInXml");
//给College实例的字段赋值(同School实例)
digester.addSetProperties("School/College");
//调用School节点对应的实例的openCollege方法
digester.addSetNext("School/College","openCollege","javax.zyl.digester.College");
//下面处理student节点,与college节点的处理方式相同
digester.addObjectCreate("School/College/Student","javax.zyl.digester.Student","classNameInXml");
digester.addSetProperties("School/College/Student");
digester.addSetNext("School/College/Student","addStudent","javax.zyl.digester.Student");
//设置digester的root
digester.push(this);
DigesterTest digesterTest = (DigesterTest)digester.parse(new File("/school.xml"));
}
public void setSchool(School school) {
this.school = school;
}
}
main方法执行完会打印出如下信息:
信息学院添加了学生:张三
信息学院添加了学生:李四
化工大学开设了专业:信息学院
生命学院添加了学生:王五
生命学院添加了学生:赵六
化工大学开设了专业:生命学院
信息学院添加了学生:李四
化工大学开设了专业:信息学院
生命学院添加了学生:王五
生命学院添加了学生:赵六
化工大学开设了专业:生命学院