tomcat如何解析META-INF目录下的context.xml

 

 

前阵子,准备重新测试一下tomcat对context.xml中数据源的处理情况,当时我的context.xml是这样写的,并且放在web目录下的META-INF目录下

 

1
2
3
4
5
6
7
xml version = '1.0' encoding = 'UTF-8' ?>
< Context >
     < resource name = "jdbc/xx" auth = "Container" type = "javax.sql.DataSource" password = "123456"
               driverClassName = "com.mysql.jdbc.Driver"
               username = "root" url = "jdbc:mysql://127.0.0.1/xx"
               />
Context >

 

并且相应的mysql.jar包已经放到tomcat的lib目录下,然后在进行运行之后,死活也找不到所配置的数据源信息。最后找了半天,错误原因也很 简单的,并不是context.xml位置不正确。在上面的xml配置中,resource节点中的resource应该写首字母大写,即应该为 Resource而不是resource。修改之后,一切正确了。

 

那么是什么原因导致tomcat找不到这里所写的小写的resource呢,这就涉及到tomcat内部对context.xml解析了。在tomcat 内部,是通过ContextConfig类来用于处理context.xml信息,并通过Digester类来完成对context.xml的解析,在具 体的解析过程中,正是因为对相应节点的匹配不成功,导致没有解析。但是不会发生错误。

 

在tomcat内部,使用ContextConfig来解析web.xml和context.xml,当仔细查看代码时,你会发现,解析web.xml和 context.xml使用的是同一个类,即org.apache.tomcat.util.digester.Digester,通过使用不同的 Rule对节点进行匹配,让匹配之后的Rule进行不同的操作,而Digester本身只做一个分发的作用,并不参与实际逻辑。整个流程可以由如下图所 示:

 

 

tomcat如何解析META-INF目录下的context.xml_第1张图片

 

那么在整个Context.xml解析中加入了哪些RuleSet呢,可以由如何创建contextDigester的过程得出,如下代码所示:(以下代码在ContextConfig类中)

 

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
     protected Digester createContextDigester() {
         Digester digester = new Digester();
         digester.setValidating( false );
         digester.setRulesValidation( true );
         HashMap, List> fakeAttributes =
             new HashMap, List>();
         ArrayList attrs = new ArrayList();
         attrs.add( "className" );
         fakeAttributes.put(Object. class , attrs);
         digester.setFakeAttributes(fakeAttributes);
         RuleSet contextRuleSet = new ContextRuleSet( "" , false ); //用于解析在context.xml中常规的context选项
         digester.addRuleSet(contextRuleSet);
         RuleSet namingRuleSet = new NamingRuleSet( "Context/" ); //用于解析如本文中的命名服务信息
         digester.addRuleSet(namingRuleSet);
         return digester;
     }

 

ContextRuleSet和NamingRuleSet是一个规则集合,在详细的addRuleInstances(Digester digester)中,才把最终的规则加入到digester中。在tomcat中,每一条规则的描述即由一个规则名和具体规则实现来表示。规则名,即从 xml根节点名到子节点名的一个完整path,如context节点下的resource节点,就表示为Context/Resource。在 NamingRuleSet中,我们可以看到为Resource节点增加了3个规则,如下所示:        

 

1
2
3
4
5
6
digester.addObjectCreate(prefix + "Resource" ,
                                  "org.apache.catalina.deploy.ContextResource" );
         digester.addRule(prefix + "Resource" , new SetAllPropertiesRule());
         digester.addRule(prefix + "Resource" ,
                 new SetNextNamingRule( "addResource" ,
                             "org.apache.catalina.deploy.ContextResource" ));

 

其中第一个规则,即创建一个ContextResource对象,即Resource的对象表示。第二个规则,就是将节点的相应属性进行设置,包括可以能 够识别的属性和通过setProperties设置的其他属性。第三个规则则是将这个对象添加到context下的namingresources集合 中。

 

通过对以上代码的了解,我们知道如果不是标准的xml节点,那么tomcat在解析中是不会解析的。因此,没有相应的解析规则可以匹配。那么,tomcat如何进一步解析本文中的resource节点,并加入到jndi中,则是下一篇文章则要分析的了。

 

转载请标明出处:i flym
本文地址:http://www.iflym.com/index.php/code/201208080002.html

你可能感兴趣的:(java)