tomcat 7 源码分析-3 使用Digester读取xml文件实例化server

本文详细解析了Tomcat启动过程中的关键步骤,重点介绍了Digester组件如何将server.xml配置文件转换为Server对象实例。

接下来tomcat要load了,看下面一些程序片段

public void load() {

        long t1 = System.nanoTime();
        initDirs();
        initNaming();
        Digester digester = createStartDigester();
        ........
       digester.push(this);
       digester.parse(inputSource);
        ........
        getServer().init();

 令人费解的如何实例化server的?digester有何作用?原来digester是apache的common项目,作用是讲XML转成Object。tomcat读取配置文件conf\server.xml,实例化server对象。形同:

        // Configure the actions we will be using
        digester.addObjectCreate("Server",
                                 "org.apache.catalina.core.StandardServer",
                                 "className");
        digester.addSetProperties("Server");
        digester.addSetNext("Server",
                            "setServer",
                            "org.apache.catalina.Server");

 要读懂这些还真费解,这里写了个小例子。

首先xml文件为

<?xml version="1.0"?>
<catalog library="somewhere">
   <book>
      <author>Author 1</author>
      <title>Title 1</title>
   </book>
   <book>
      <author>Author 2</author>
      <title>His One Book</title>
   </book>
   <book>
      <author>Author 3</author>
      <title>His Other Book</title>
   </book>
</catalog>

 Book.java

package com.xiao;

public class Book {
	   private String author;
	   private String title;

	   public Book() {}

	   public void setAuthor( String rhs ) { author = rhs; }
	   public void setTitle(  String rhs ) { title  = rhs; }
	   
	   public String getAuthor(  ) { return author; }
	   public String getTitle(  ) { return title; }
	   
	   public String toString() {
	      return "Book: Author='" + author + "' Title='" + title + "'";
	   }
	}

Catalog.java

package com.xiao;
import java.util.Vector;
public class Catalog {
   private Vector<Book> books;

   public Catalog() {
      books = new Vector<Book>();
   }
   public void addBook( Book rhs ) {
      books.addElement( rhs );
   }
   public String toString() {
      String newline = System.getProperty( "line.separator" );
      StringBuffer buf = new StringBuffer();
      buf.append( "--- Books ---" ).append( newline );
      for( int i=0; i<books.size(); i++ ){
    	  Book book  = books.elementAt(i);
         buf.append( book.toString()).append( newline );
      }
      return buf.toString();
   }
}

 CreateCatalog.java

package com.xiao;
import java.io.IOException;
import org.apache.tomcat.util.digester.Digester;
import org.xml.sax.SAXException;

public class CreateCatalog {
	protected  Catalog ct;
	
	public void SetCatalog(Catalog ol){
		
		ct = ol;
	}
	
	public Catalog GetCatalog(){
		
		return this.ct;
	}
	public String toString() {
		
		return ct.toString();
		}
	
	public Digester createStartDigester()throws IOException, SAXException
	{
		Digester digester = new Digester();
		digester.setValidating( false );
		//解析XML时,遇到catalog,就实例化一个com.xiao.Catalog对象,并且压栈
		digester.addObjectCreate( "catalog", "com.xiao.Catalog");
		//对catalog,调用栈的次top对象(现在还没有压入,父对象)的SetCatalog函数。
		//passing the element that is on the top of the stack, which must be of type com.xiao.Catalog
		//This is the rule that causes the parent/child relationship to be created.
		digester.addSetNext("catalog", "SetCatalog", "com.xiao.Catalog");
		
		digester.addObjectCreate( "catalog/book","com.xiao.Book");
		
		//对rule,调用当前top object的setAuthor函数,参数个数为1
		digester.addCallMethod("catalog/book/author", "setAuthor",1);
		//对rule,添加第一个参数值
		digester.addCallParam("catalog/book/author", 0);
		digester.addCallMethod("catalog/book/title", "setTitle",1);
		digester.addCallParam("catalog/book/title", 0);
		//此时次top的object就是com.xiao.Catalog,调用它的addBook函数,将com.xiao.Book传入
		digester.addSetNext("catalog/book", "addBook", "com.xiao.Book");
		
		return (digester);
	}
}

 TestDigester.java

package com.xiao;

import org.apache.tomcat.util.digester.Digester;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.*;
public class TestDigester {
	
	public static void main(String[] args) throws IOException, SAXException  {
		// TODO Auto-generated method stub
		CreateCatalog cc = new CreateCatalog();
		Digester digester = cc.createStartDigester();	
		String configFile = "xiapingtest/ts.xml";	
		InputSource inputSource = null;
		InputStream inputStream = null;
		File file = new File(System.getProperty("user.dir"),configFile);
		inputSource = new InputSource("file://" + file.getAbsolutePath());
		inputStream = new FileInputStream(file);
		inputSource.setByteStream(inputStream);
		//在加入CreateCatalog对象,这个是第一个压入的对象
		digester.push(cc);
		//处理xml文件,逐个加入对象
		digester.parse(inputSource);		
		System.out.println(cc.toString());
	}

}

 部分解释以及在代码注释里。

采用PyQt5框架与Python编程语言构建图书信息管理平台 本项目基于Python编程环境,结合PyQt5图形界面开发库,设计实现了一套完整的图书信息管理解决方案。该系统主要面向图书馆、书店等机构的日常运营需求,通过模块化设计实现了图书信息的标准化管理流程。 系统架构采用典型的三层设计模式,包含数据存储层、业务逻辑层和用户界面层。数据持久化方案支持SQLite轻量级数据库与MySQL企业级数据库的双重配置选项,通过统一的数据库操作接口实现数据存取隔离。在数据建模方面,设计了包含图书基本信息、读者档案、借阅记录等核心数据实体,各实体间通过主外键约束建立关联关系。 核心功能模块包含六大子系统: 1. 图书编目管理:支持国际标准书号、中国图书馆分类法等专业元数据的规范化著录,提供批量导入与单条录入两种数据采集方式 2. 库存动态监控:实时追踪在架数量、借出状态、预约队列等流通指标,设置库存预警阈值自动提醒补货 3. 读者服务管理:建立完整的读者信用评价体系,记录借阅历史与违规行为,实施差异化借阅权限管理 4. 流通业务处理:涵盖借书登记、归还处理、续借申请、逾期计算等标准业务流程,支持射频识别技术设备集成 5. 统计报表生成:按日/月/年周期自动生成流通统计、热门图书排行、读者活跃度等多维度分析图表 6. 系统维护配置:提供用户权限分级管理、数据备份恢复、操作日志审计等管理功能 在技术实现层面,界面设计遵循Material Design设计规范,采用QSS样式表实现视觉定制化。通过信号槽机制实现前后端数据双向绑定,运用多线程处理技术保障界面响应流畅度。数据验证机制包含前端格式校验与后端业务规则双重保障,关键操作均设有二次确认流程。 该系统适用于中小型图书管理场景,通过可扩展的插件架构支持功能模块的灵活组合。开发过程中特别注重代码的可维护性,采用面向对象编程范式实现高内聚低耦合的组件设计,为后续功能迭代奠定技术基础。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值