Tomcat 8(八)Tomcat解析server.xml的工具—Digester
来源:互联网 发布:开淘宝怎么上传照片 编辑:程序博客网 时间:2024/05/01 07:00
Tomcat是利用Digester解析server.xml。Digester是Apache下的开源项目
Digester官网:http://commons.apache.org/proper/commons-digester/
使用Digester,需要依赖一些jar包。Digester依赖的jar包可以从网上下载,也可以使用Tomcat提供的jar包
方案一:从网上下载jar包
commons-beanutils.jar
commons-digester.jar
commons-logging.jar
commons-collections.jar(下载commons-collections-3。commons-collections-4将commons-collections的package命名由org.apache.commons.collections改为org.apache.commons.collections4,而Digester内部仍按org.apache.commons.collections使用的)
方案二:使用Tomcat目录下的jar包
tomcat-juli.jar($CATALINA_HOME\bin)
tomcat-util.jar($CATALINA_HOME\lib)
tomcat-util-scan.jar($CATALINA_HOME\lib)
本文采用方案一
下面来看看Digester如何解析School.xml
<?xml version='1.0' encoding='utf-8'?><School name="CSDN"><Grade name="1"><Class name="1" number="31"/><Class name="2" number="32"/></Grade><Grade name="2"><Class name="1" number="41"/><Class name="2" number="42"/></Grade></School>
School是School.xml的最顶层节点,School节点下包含Grade节点,Grade节点下包含Class节点。(学校下有两个年级,每个年级下有两个班级,班级下的number表示人数)
首先要创建与School.xml中各个节点对应的实体类School.java、Grade.java、Class.java(这些类都放在digester包下)
School.java
package digester;public class School {private String name;private Grade grades[] = new Grade[0];private final Object servicesLock = new Object();public void addGrade(Grade g){synchronized (servicesLock) {Grade results[] = new Grade[grades.length + 1]; System.arraycopy(grades, 0, results, 0, grades.length); results[grades.length] = g; grades = results; }}public Grade[] getGrades() {return grades;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
School里的Grade数组用来存放School包含的Grade。调用School. addGrade(Grade g),可以往Grade数组添加Grade
Grade.java
package digester;public class Grade {private String name;private Class classes[] = new Class[0];private final Object servicesLock = new Object();public void addClass(Class c){synchronized (servicesLock) {Class results[] = new Class[classes.length + 1]; System.arraycopy(classes, 0, results, 0, classes.length); results[classes.length] = c; classes = results; }}public Class[] getClasses() {return classes;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
Class.java
package digester;public class Class {private String name;private int number;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}}
然后创建测试类DigesterTest.java。DigesterTest.java的digester方法用来读取School.xml、创建Digester并设置规则、解析School.xml;print方法用来打印School的信息
package digester;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import org.apache.tomcat.util.digester.Digester;import org.xml.sax.InputSource;import org.xml.sax.SAXException;public class DigesterTest {private School school;public School getSchool() {return school;}public void setSchool(School s) {this.school = s;}public void digester() throws IOException, SAXException{//读取School.xmlFile file = new File("D:\\School.xml");InputStream inputStream = new FileInputStream(file);InputSource inputSource = new InputSource(file.toURI().toURL().toString());;inputSource.setByteStream(inputStream);//创建Digester Digester digester = new Digester(); //是否需要用DTD验证XML文档的合法性 digester.setValidating(false); //将当前对象放到对象堆的最顶层 digester.push(this); /* 下面开始为Digester创建匹配规则 * 在Digester内School、School/Grade、School/Grade/Class * 分别对应School.xml的School、Grade、Class节点 */ //为School创建规则 /* * Digester.addObjectCreate(String pattern, String className, String attributeName) * pattern--匹配的节点 * className--该节点对应的默认实体类 * attributeName--如果该节点有className属性,用className的值替换默认实体类 * Digester匹配到School节点,如果School节点没有className属性,将创建digester.School对象;如果School节点有className属性,将创建指定的(className属性的值)对象 */ digester.addObjectCreate("School", "digester.School", "className"); //将指定节点的属性映射到对象,即将School节点的name的属性映射到School.java digester.addSetProperties("School"); /* * Digester.addSetNext(String pattern, String methodName, String paramType) * pattern--匹配的节点 * methodName--调用父节点的方法 * paramType--父节点的方法接收的参数类型 * Digester匹配到School节点,将调用DigesterTest(School的父节点)的setSchool方法,参数为School对象 */ digester.addSetNext("School", "setSchool", "digester.School"); //为School/Grade创建规则 digester.addObjectCreate("School/Grade", "digester.Grade", "className"); digester.addSetProperties("School/Grade"); //Grade的父节点为School digester.addSetNext("School/Grade", "addGrade", "digester.Grade"); //为School/Grade/Class创建规则 digester.addObjectCreate("School/Grade/Class", "digester.Class", "className"); digester.addSetProperties("School/Grade/Class"); digester.addSetNext("School/Grade/Class", "addClass", "digester.Class"); digester.parse(inputSource);}//打印School信息public void print(School s){if(s!=null){System.out.println(s.getName() + "有" + s.getGrades().length + "个年级");for(int i=0;i<s.getGrades().length;i++){if(s.getGrades()[i] !=null){Grade g = s.getGrades()[i];System.out.println(g.getName() + "年级 有 " + g.getClasses().length + "个班:");for(int j=0;j<g.getClasses().length;j++){if(g.getClasses()[j] !=null){Class c = g.getClasses()[j];System.out.println(c.getName() + "班有" + c.getNumber() + "人");}}}}}}public static void main(String[] args) throws IOException, SAXException {DigesterTest digesterTest = new DigesterTest();digesterTest.digester();digesterTest.print(digesterTest.school);}}
DigesterTest的输出:
CSDN有2个年级1年级 有 2个班:1班有31人2班有32人2年级 有 2个班:1班有41人2班有42人
Tomcat解析server.xml是在Catalina的load方法内进行的。load方法可以划分成三步:
1. 创建Digester并设置规则
load方法内通过Digester digester = createStartDigester()创建Digester 并设置规则。createStartDigester也是Catalina内的方法
createStartDigester方法的内容(为了简介,每种创建规则的方式各列一个)
protected Digester createStartDigester() { Digester digester = new Digester(); digester.setValidating(false); digester.setRulesValidation(true); HashMap<Class<?>, List<String>> fakeAttributes = new HashMap<>(); ArrayList<String> attrs = new ArrayList<>(); attrs.add("className"); fakeAttributes.put(Object.class, attrs); digester.setFakeAttributes(fakeAttributes); digester.setUseContextClassLoader(true); digester.addObjectCreate("Server", "org.apache.catalina.core.StandardServer", "className"); digester.addSetProperties("Server"); //父节点为Catalinadigester.addSetNext("Server", "setServer", "org.apache.catalina.Server"); digester.addObjectCreate("Server/Service", "org.apache.catalina.core.StandardService", "className"); digester.addSetProperties("Server/Service");//父节点为Server digester.addSetNext("Server/Service", "addService", "org.apache.catalina.Service");//为Connector节点创建规则 digester.addRule("Server/Service/Connector", new ConnectorCreateRule()); /* * 如果某个节点包含的规则比较多,可以为该节点创建一个规则类 * 执行digester.addRuleSet(new EngineRuleSet("Server/Service/")) * 可以将EngineRuleSet内包含的规则,添加到当前digester中 */ digester.addRuleSet(new EngineRuleSet("Server/Service/"));//为Cluster节点创建规则 addClusterRuleSet(digester, "Server/Service/Engine/Host/Cluster/"); }
2. 读取server.xml文件
InputSource inputSource = null; InputStream inputStream = null; File file = null; try { file = configFile(); inputStream = new FileInputStream(file); inputSource = new InputSource(file.toURI().toURL().toString()); } catch (Exception e) { if (log.isDebugEnabled()) { log.debug(sm.getString("catalina.configFail", file), e); } }
3. 利用Digester解析xml文件
try { inputSource.setByteStream(inputStream); digester.push(this); digester.parse(inputSource); } catch (SAXParseException spe) { log.warn("Catalina.start using " + getConfigFile() + ": " + spe.getMessage()); return; } catch (Exception e) { log.warn("Catalina.start using " + getConfigFile() + ": " , e); return; } finally { try { inputStream.close(); } catch (IOException e) { // Ignore } }
参考文章:
http://blog.csdn.net/caihaijiang/article/details/5944955
http://www.cnblogs.com/bjzhanghao/archive/2005/03/25/125747.html
- Tomcat 8(八)Tomcat解析server.xml的工具—Digester
- Tomcat 8(八)Tomcat解析server.xml的工具—Digester
- Tomcat中Digester解析server.xml文件
- Tomcat源码的catalina中利用Digester解析conf/server.xml
- Tomcat源码的catalina中利用Digester解析conf/server.xml
- Tomcat中xml的解析器Digester 第二篇(共三篇)
- Digester(xml解析工具)
- xml解析工具Digester
- 理解Tomcat(一) 利用Digester解析xml文件
- tomcat之catalina使用Digester解析XML配置文件
- tomcat解析(五)Digester(一)
- tomcat源码中Digester解析
- Tomcat的服务器配置文件server.xml解析
- Tomcat的服务器配置文件server.xml解析
- Tomcat的服务器配置文件server.xml解析
- Tomcat的server.xml配置文件解析
- tomcat源码浅析(二)之server.xml的解析
- tomcat server.xml配置解析
- 遗传算法和一些思考
- 北大OJ百练——4074:积水量(C语言)
- 网友gforceca1900关于C++11的评论
- 分布式游戏服务器端框架 Firefly
- 研究相关的博客
- Tomcat 8(八)Tomcat解析server.xml的工具—Digester
- 选择排序
- UNIX LINUX 系统 命令
- ARM汇编程序中学ARM程序的结构和混合编程
- Jquery使用小技巧(1)
- [C++]inline函数
- 数组、List以及Map的遍历
- JDK概述
- B - Break Standard Weight