How tomcat work 之 第十五章之Digester之ContextConfig之the defaultConfig Method


the defaultConfig Method


defaultConfig方法读取和解析默认的web.xml文件,这个文件在CATALINA_HOME/conf目录下。其代码清单如15.13所示:


private void defaultConfig() {
         // Open the default web.xml file, if it exists
         File file = new File(Constants.DefaultWebXml);
         if (!file.isAbsolute())
              file = new File(System.getProperty("catalina.base"),Constants.DefaultWebXml);
          FileInputStream stream = null;
          try{
                stream = new FileInputStream(file.getCanonicalPath());
                 stream.close();
                 stream = null;
               }
               catch (FileNotFoundException e) {
             log(sm.getString("contextConfig.defaultMissing"));
             return;
        }
         catch (IOException e) {
              log(sm.getString("contextConfig.defaultMissing"), e);
              return;
          }
          // Process the default web.xml file
          synchronized (webDigester) {
              try {
                       InputSource is =new InputSource("file://" + file.getAbsolutePath());
                       stream = new FileInputStream(file);
                        is.setByteStream(stream);
                        webDigester.setDebug(getDebug());
                         if (context instanceof StandardContext)
                             ((StandardContext) context).setReplaceWelcomeFiles(true);
                          webDigester.clear();
                          webDigester.push(context);
                          webDigester.parse(is);
          catch (SAXParseException e) {
                    log(sm.getString("contextConfig.defaultParse"), e);
                    log(sm.getString("contextConfig.defaultPosition","" + e.getLineNumber(), "" + e.getColumnNumber()));
                    ok = false;
                 }
          catch (Exception e) {
                log(sm.getString("contextConfig.defaultParse"), e);
                ok = false;
          }
          finally {
                    try {
                           if (stream != null) {
                                     stream.close();
                             }
                        }
                    catch (IOException e) {
                            log(sm.getString("contextConfig.defaultClose"), e);
                    }
                }
          }
  }




defaultConfig方法首先创建一个与default.xml文件相关联的文件对象。


File file = new File(Constants.DefaultWebXml);


DefaultWebXML的值是在一个常量类中定义:


public static final String DefaultWebXml = "conf/web.xml";


defaultConfig方法稍后处理web.xml文件。其持有webDigester的内部锁,之后解析文件:


synchronized (webDigester) {
      try {
         InputSource is =
            new InputSource("file://" + file.getAbsolutePath());
         stream = new FileInputStream(file); 
         is.setByteStream(stream);
         webDigester.setDebug(getDebug());
         if (context instanceof StandardContext)
             ((StandardContext) context).setReplaceWelcomeFiles(true);
         webDigester.clear();
         webDigester.push(context);
         webDigester.parse(is);


与Digester实例关联的webDigester对象已经设置了处理web.xml文件的规则。这会在稍后的章节中讲解。


the applicationConfig method


这个方法与defaultConfig方法相似,除了它处理的是应用部署描述符。部署描述符位于应用程序目录的WEB-INF目录下。


private void applicationConfig() {
    // Open the application web.xml file, if it exists
    InputStream stream = null;
    ServletContext servletContext = context.getServletContext();
     if (servletContext != null)
         stream = servletContext.getResourceAsStream(Constants.ApplicationWebXml);
     if (stream == null) {
         log(sm.getString("contextConfig.applicationMissing"));
         return;
     }

     // Process the application web.xml file
     synchronized (webDigester) {
         try {
              URL url =
                  servletContext.getResource(Constants.ApplicationWebXml);
               
              InputSource is = new InputSource(url.toExternalForm());
              is.setByteStream(stream);
              webDigester.setDebug(getDebug());
              if (context instanceof StandardContext) {
                   ((StandardContext) context).setReplaceWelcomeFiles(true);
              }
              webDigester.clear();
              webDigester.push(context);
              webDigester.parse(is);
           }
           catch (SAXParseException e) {
              log(sm.getString("contextConfig.applicationParse"), e);
              log(sm.getString("contextConfig.applicationPosition","" + e.getLineNumber(),"" + e.getColumnNumber()));
              ok = false;
         }
         catch (Exception e) {
             log(sm.getString("contextConfig.applicationParse"), e);
             ok = false;
         }
         finally { 
             try {
                  if (stream != null){
                       stream.close();
                   }
              }
              catch (IOException e) {
                 log(sm.getString("contextConfig.applicationClose"),e);
              }
            }
          }
      }      


create Web Digester

一个Digester对象引用,叫做webDigester,存在于ContextConfig类中:


private static Digester webDigester = createWebDigester();


Digester用于解析默认的web.xml和应用程序中的web.xml文件。当调用createWebDigester方式时,添加处理web.xml文件的规则。其代码清单如下:


private static Digester createWebDigester() {
    URL url = null;
    Digester webDigester = new Digester();
    webDigester.setValidating(true);
    url = ContextConfig.class.getResource(Constants.WebDtdResourcePath_22);
    webDigester.register(Constants.WebDtdPublicId_22,url.toString());
    url = ContextConfig.class.getResource(Constants.WebDtdResourcePath_23);
    webDigester.register(Constants.WebDtdPublicId_23,url.toString());
    url.toString());
    webDigester.addRuleSet(new WebRuleSet());
    return (webDigester);
}     
    



注意 createWebDigester方法调用了webDigester的addRuleSet方法,来解析WebRuleSet的一个实例。WebRuleSet是RuleSetBase的一个子类。如果熟悉一个Servlet应用程序的部署描述符的语法并且阅读了这章开头的Digester部分,你应该能够理解其实如何工作的。


WebRuleSet的代码清单如下。注意为了节省空间,移除了addRuleInstance部分。

package org.apache.catalina.startup;

import java.lang.reflect.Method;
import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.apache.catalina.deploy.SecurityConstraint;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.RuleSetBase;
import org.xml.sax.Attributes;


public class WebRuleSet extends RuleSetBase {
    protected String prefix = null;
    public WebRuleSet () {
        this("");
    }

    public WebRuleSet(String prefix) {
        super();
        this.namespaceURI = null;
        this.prefix = prefix;
    }

    public void addRuleInstances(Digester digester) {
        digester.addRule(prefix + "web-app",new SetPublicIdRule(digester, "setPublicId"));
        digester.addCallMethod(prefix + "web-app/context-param","addParameter", 2);
        digester.addCallParam(prefix +"web-app/context-param/param-name", 0); 
        digester.addCallParam(prefix +"web-app/context-param/param-value", 1); 
        digester.addCallMethod(prefix + "web-app/display-name","setDisplayName", 0);
        digester.addRule(prefix + "web-app/distributable",new SetDistributableRule(digester));
        ...
        digester.addObjectCreate(prefix + "web-app/filter","org.apache.catalina.deploy.FilterDef");
        digester.addSetNext(prefix + "web-app/filter", "addFilterDef","org.apache.catalina.deploy.FilterDef");
        digester.addCallMethod(prefix + "web-app/filter/description","setDescription", 0);
        digester.addCallMethod(prefix + "web-app/filter/display-name",  "setDisplayName", 0);
        digester.addCallMethod(prefix + "web-app/filter/filter-class","setFilterClass", 0);
        digester.addCallMethod(prefix + "web-app/filter/filter-name","setFilterName", 0);
        digester.addCallMethod(prefix + "web-app/filter/large-icon","setLargeIcon", 0);
        digester.addCallMethod(prefix + "web-app/filter/small-icon","setSmallIcon", 0);
        digester.addCallMethod(prefix + "web-app/filter/init-param","addInitParameter", 2);
        digester.addCallParam(prefix +"web-app/filter/init-param/param-name", 0);
        digester.addCallParam(prefix +"web-app/filter/init-param/param-value", 1);
        digester.addObjectCreate(prefix + "web-app/filter-mapping","org.apache.catalina.deploy.FilterMap");
        digester.addSetNext(prefix + "web-app/filter-mapping","addFilterMap", "org.apache.catalina.deploy.FilterMap");
        digester.addCallMethod(prefix +"web-app/filter-mapping/filter-name", "setFilterName", 0);
        digester.addCallMethod(prefix +"web-app/filter-mapping/servlet-name", "setServletName", 0);
        digester.addCallMethod(prefix +"web-app/filter-mapping/url-pattern", "setURLPattern", 0);
        digester.addCallMethod (prefix +"web-app/listener/listener-class", "addApplicationListener", 0);
        ...
        digester.addRule(prefix + "web-app/servlet",new WrapperCreateRule(digester));
        digester.addSetNext(prefix + "web-app/servlet","addChild", "org.apache.catalina.Container");
        digester.addCallMethod(prefix + "web-app/servlet/init-param","addInitParameter", 2);
        digester.addCallParam(prefix +"web-app/servlet/init-param/param-name", 0);
        digester.addCallParam(prefix +"web-app/servlet/init-param/param-value", 1);
        digester.addCallMethod(prefix + "web-app/servlet/jsp-file","setJspFile", 0);
        digester.addCallMethod(prefix +"web-app/servlet/load-on-startup", "setLoadOnStartupString", 0);
        digester.addCallMethod(prefix +"web-app/servlet/run-as/role-name", "setRunAs", 0);
        digester.addCallMethod(prefix +"web-app/servlet/security-role-ref", "addSecurityReference", 2);
        digester.addCallParam(prefix +"web-app/servlet/security-role-ref/role-link", 1);
        digester.addCallParam(prefix +"web-app/servlet/security-role-ref/role-name", 0);
        digester.addCallMethod(prefix + "web-app/servlet/servlet-class","setServletdass", 0);
        digester.addCallMethod(prefix + "web-app/servlet/servlet-name","setName", 0);
        digester.addCallMethod(prefix + "web-app/servlet-mapping","addServletMapping", 2);
        digester.addCallParam(prefix +"web-app/servlet-mapping/servlet-name"/ 1);
        digester.addCallParam(prefix +"web-app/servlet-mapping/url-pattern", 0);
        digester.addCallMethod (prefix +"web-app/session-config/session-timeout", "setSessionTimeout", 1,new Class[] { Integer.TYPE });
        digester.addCallParam(prefix +"web-app/session-config/session-timeout", 0);
        digester.addCallMethod(prefix + "web-app/taglib","addTaglib", 2);
        digester.addCallParam(prefix + "web-app/taglib/taglib-location",1);
        digester.addCallParam(prefix + "web-app/taglib/taglib-uri", 0);
        digester.addCallMethod(prefix +"web-app/welcome-file-list/welcome-file", "addWelcomeFile", 0);
        }
     }

 // --------------------------------------------- Private Classes
  final class SetAuthConstraintRule extends Rule {
      public SetAuthConstraintRule(Digester digester) {
          super(digester);
      }
      public void begin(Attributes attributes) throws Exception {
          SecurityConstraint securityConstraint = (SecurityConstraint) digester.peek();
          securityConstraint.setAuthConstraint(true);
           if (digester.getDebug() > 0)
               digester.log("Calling
 SecurityConstraint.setAuthConstraint(true)");
    }
}

...

final class WrapperCreateRule extends Rule {
    public WrapperCreateRule(Digester digester) {
         super(digester);
    }

    public void begin(Attributes attributes) throws Exception {
        Context context =(Context) digester.peek(digester.getCount() - 1);
         Wrapper wrapper = context.createWrapper();
            digester.push(wrapper);
          if (digester.getDebug() > 0)
              digester.log("new " + wrapper.getClass().getName());
 }

public void end() throws Exception {
    Wrapper wrapper = (Wrapper) digester.pop();
     if (digester.getDebug() > 0)
         digester.log("pop " + wrapper.getclass().getName());
  }
}
                
                   
         







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值