理解Tomcat(一) 利用Digester解析xml文件

Tomcat与Digester的关系

我们利用Tomcat做服务器开发Web应用时,总会有一个配置文件web.xml,进行一些对象的实例化或是Servlet的映射的配置,所以要想理解Tomcat的一些配置问题,首先需要了解Tomcat是如何利用xml文件来进行配置的?答案就是利用开源的Digest进行XML的解析,然后构建响应的容器或者完成其他的配置,这些我会在单篇文章中具体深入讲解,作为这个专题的第一个部分,就首先避重就轻地讲解一下Digester这个开源的xml解析工具

Digester

org.apache.commons.digester

该包提供了基于规则的,可任意处理XML文档的类

org.apache.commons.digester.Digester是Digester类库的主类,该类可用于解析XML文档。
  • 解析过程分为两步:
    • 定义好模式(定义要匹配的标签)
    • 将模式与规则(定义匹配到标签后的行为的对象)相关联
  • 模式规则
    • 模式:
      模式由如下形式的字符串拼接而成:
      父元素的模式+”/”+子元素的模式
    • 规则:
      一条规则指明了当Digester对象匹配到了指定的模式触发的一个或多个动作。
      • 规则是org.apache.commons.digester.Rule类的实例
      • Rule类有begin()方法end()方法。在解析XML文档时,
        • 当Digester实例匹配到某个模式的开始标签时,它会相应地调用Rule的begin()方法
        • 当Digester实例匹配到某个模式的结束标签时,它会相应地调用Rule的end()方法
Digester库已经预定义了一些规则。可以直接使用这些规则而无须深入理解Rule类的实现
  • 规则一:创建对象
    在遇到指定模式时创建对象可以调用addObjectCreate()方法

    • 通过模式和创建对象的类进行调用
    public void addObjectCreate( String pattern , Class class )
    public void addObjectCreate( String pattern , String className)
    • 可以在XML中通过属性指定类进行实例化重载
    public void addObjectCreate( String pattern , String className , String attributeName ) 
    public void addObjectCreate(String pattern , String attributeName , Class class )
    • addObjectCreate()方法创建的对象会被压入一个内部栈中,Digester库负责维护这个内部栈
  • 规则二:设置属性
public void addSetProperties( String pattern )

利用pattern匹配到的标签内的属性设置实例的属性,一般紧跟addObjectCreate使用,如:

<Student age="12" height="1.8"/>

就可以在生成实例后,利用age和height属性初始化对象student中的同名属性

  • 规则三:调用方法
    Digester类允许添加一条规则,若模式得到匹配,可以调用内部栈顶部的对象的某个方法
public void addCallMethod(String pattern , String methodName )
  • 规则四:创建对象之间的关系
    • 我们之前有提过,Digester实例有一个内部栈,用于存储临时的对象。当使用addObjectCreate()方法实例化一个类时,会把结果压入这个栈中。
    • 当调用了两次addObjectCreate()方法时,会有两个对象被放入栈中,这时候调用addSetNext()方法会调用第一个放入栈中的对象的方法,并将第二个对象作为参数,设置第一个对象和第二个对象的关系
public void addSetNext ( String pattern , String methodName )
例讲Digester类的使用

首先呢,为了能够正常使用Digester,我们需要下载它运行所需要的类结构:
这里写图片描述
如果登陆了CSDN账号的话,可以在如下的链接下载,由我免费提供^_^
commons-digester.jar
commons-collections.jar
commons-logging.jar
commons-beanutils.jar

  • 环境配置好了,我们应该构造情景,我们的情景就是解析xml中学生和课程对象的初始化,xml文件如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<student name="llin" age="16" grade="3">
    <subjects name="math" teacher="yu" />
</student>
  • 创建我们需要实例化的两个对象的类
import java.util.ArrayList;

/**
 * Created by liulin on 16-5-1.
 */
public class Student {
    private String name;
    private int age;
    private int grade;
    private ArrayList<Subjects> list = new ArrayList();
    public Student (){
        System.out.println("A student go to school");
    }

    public void add ( Subjects subjects ){
        System.out.println("add Subjects" + subjects.getName() + "to the Student: "+ this.getName());
        list.add( subjects );
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println( "set age of Student:" + name);
        this.age = age;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        System.out.println( " set score of Student:" + name );
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println(" set name pf Student" );
        this.name = name;
    }

    public ArrayList<Subjects> getList (){
        return this.list;
    }
}
/**
 * Created by liulin on 16-5-1.
 */
public class Subjects {
    private String name;
    private String teacher;

    public Subjects() {
        System.out.println("One subjects waiting scheduling!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("set name of Subjects:" + name);
        this.name = name;
    }

    public String getTeacher() {
        return teacher;
    }

    public void setTeacher(String teacher) {
        System.out.println("set teacher of Subjects :" + teacher);
        this.teacher = teacher;
    }

    public void print() {
        System.out.println("Subjects  :" + name + "of " + teacher + "in schedule");
    }
}
  • 最后就是我们利用Digester进行解析的代码了
import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Created by liulin on 16-5-1.
 */

public class DigesterTest {

    public static void main ( String [] args ) throws IOException{
        File xml = new File( "/home/liulin/byj/test.xml");
        Digester digester = new Digester();
        digester.addObjectCreate( "student" , "Student" );
        digester.addSetProperties("student");
        digester.addObjectCreate("student/subjects" , "Subjects");
        digester.addSetProperties("student/subjects");
        digester.addSetNext("student/subjects" , "add" );
        Student student = null;
        try {
            student = (Student)digester.parse(xml);
        }catch ( SAXException e ){
            System.out.println("parse with mistakes!");
        }
        Iterator it = student.getList().iterator();
        while ( it.hasNext()) {

        }
    }
}
  • 测试的结果如下:
    这里写图片描述

Rule

我们可以通过自己实现Rule类构造一个自己的Rule规则(覆写begin()和end()方法),但是大多数的情况下,都没有这个必要….
可以通过如下方法添加规则:

public void addRule( String pattern , Rule rule )

RuleSet

我们可以通过继承RuleSetBase构造自己的RuleSet,这个是很实用的
因为我们可以将一大串的规则封装成一个单一的规则,更方便使用,屏蔽了更多的细节

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSetBase;

/**
 * Created by liulin on 16-5-1.
 */
public class RuleSet  extends RuleSetBase{
    @Override
    public void addRuleInstances(Digester digester) {
        digester.addObjectCreate( "student" , "Student" );
        digester.addSetProperties("student");
        digester.addObjectCreate("student/subjects" , "Subjects");
        digester.addSetProperties("student/subjects");
        digester.addSetNext("student/subjects" , "add" );
    }
}

然后我们看我们的主体代码,更加简洁易懂了

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Created by liulin on 16-5-1.
 */

public class DigesterTest {

    public static void main ( String [] args ) throws IOException{
        File xml = new File( "/home/liulin/byj/test.xml");
        Digester digester = new Digester();
        digester.addRuleSet( new RuleSet ());
        Student student = null;
        try {
            student = (Student)digester.parse(xml);
        }catch ( SAXException e ){
            System.out.println("parse with mistakes!");
        }
        Iterator it = student.getList().iterator();
        while ( it.hasNext()) {

        }
    }
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值