标签:
2.1)problem:如下面的代码,Bootstrap类实例化连接器,servlet容器,Wrapper容器和其它组件,如设置连接器的关联顶层容器,通过set方法将它们联系起来;如监听器组件通过addLifecycleListener来设置等等。这种配置应用程序的方法有一个明显的缺点:即所有的配置都必须硬编码。调整组件配置或属性值都必须要重新编译Bootstrap类。2.2)solution:Tomcat使用了一种更加优雅的配置方式,即使用一个名为server.xml 的XML 文档来对应用程序进行配置。server.xml文件中的每个元素都会转换为一个java 对象,元素的属性会用于设置java对象 的属性。这样,就可以通过简单地编辑 server.xml文件来修改tomcat的配置了;
<context docBase="myApp" path="/myApp" />
A1)tomcat使用了开源库Digester来将XML 文档中的元素转换成 java 对象;(干货——开源库Digester的作用)A2)用来配置web 应用程序的XML 文件的名称是 web.xml,该文件位于web 应用程序的WEB-INF 目录下;(干货——引入了大家熟悉的web.xml)
public final class Bootstrap1 {
public static void main(String[] args) {
//invoke: http://localhost:8080/app1/Primitive or http://localhost:8080/app1/Modern
System.setProperty("catalina.base", System.getProperty("user.dir"));
Connector connector = new HttpConnector();
Wrapper wrapper1 = new StandardWrapper();
wrapper1.setName("Primitive");
//wrapper1.setServletClass("servlet.PrimitiveServlet");
wrapper1.setServletClass("PrimitiveServlet");
Wrapper wrapper2 = new StandardWrapper();
wrapper2.setName("Modern");
//wrapper2.setServletClass("servlet.ModernServlet");
wrapper2.setServletClass("ModernServlet");
Context context = new StandardContext();
// StandardContext's start method adds a default mapper
context.setPath("/app1");
context.setDocBase("app1");
context.addChild(wrapper1);
context.addChild(wrapper2);
LifecycleListener listener = new SimpleContextConfig();
((Lifecycle) context).addLifecycleListener(listener);
Host host = new StandardHost();
host.addChild(context);
host.setName("localhost");
host.setAppBase("webapps");
Loader loader = new WebappLoader();
context.setLoader(loader);
// context.addServletMapping(pattern, name);
context.addServletMapping("/Primitive", "Primitive");
context.addServletMapping("/Modern", "Modern");
connector.setContainer(host);
try {
connector.initialize();
((Lifecycle) connector).start();
((Lifecycle) host).start(); // 与以往的Bootstrap.java不同的是,这里是host.start() 而不是 context.start()
// make the application wait until we press a key.
System.in.read();
((Lifecycle) host).stop();
}
catch (Exception e) {
e.printStackTrace();
}
}
}package1)org.apache.commons.digester:该包提供了基于规则的,可处理任意XML 文档的类;package2)org.apache.commons.digester.rss:该包包含一些可以用来解析与很多新闻源使用的RSS(Rich Site Summary,富站点摘要)格式兼容的XML文档的例子;package3)org.apache.commons.digester.xmlrules:该包为 Digester库提供了一些基于XML规则的定义;
<?xml version=1.0" encoding="ISO-8859-1">
<employee firstName="pacoson" lastName="xiao">
<office>
<address streetName="Wellington Street" streetNumber="110" />
</office>
</employee>A1)该XML文档中的根元素是 employee,employee元素有一个模式, 名为 employee;A2)office元素是 employee元素的子元素,子元素的模式是由该元素的父元素的模式再加上 “/” 符号,以及该元素名称拼接而成的,所以office元素的模式是 employee/office;(干货——我们这就了解了如何从XML 文档中推导出元素的模式)
rule1)一条规则指明了当Digester 对象遇到了某个特殊的模式时要执行的一个或多个动作;规则是 org.apache.commons.digester.Rule 类;Digester类可以包含0个或多个对象;rule2)Rule类有begin()方法 和 end() 方法。在开始标签调用start()方法,结束标签调用 end() 方法;
public void addObjectCreate(String pattern, String className) {
addRule(pattern, new ObjectCreateRule(className));
}
public void addObjectCreate(String pattern, Class clazz) {
addRule(pattern, new ObjectCreateRule(clazz));
}
public void addObjectCreate(String pattern, String className, String attributeName) {
addRule(pattern, new ObjectCreateRule(className, attributeName));
}
public void addObjectCreate(String pattern, String attributeName, Class clazz) {
addRule(pattern, new ObjectCreateRule(attributeName, clazz));
}看个荔枝)如我们想让Digester对象在遇到模式employee 时,创建一个 mydiy.Employee 对象,则使用下面的代码来调用 addObjectCreate()方法:A1)需要传入一个模式和一个Class对象或类名来调用该方法;
digester.addObjectCreate("employee", "mydiy.Employee.class"); 或者 digester.addObjectCreate("employee", "mydiy.Employee");A2)addObjecdtCreate()方法的最后两个重载版本允许在xml 文档中定义类的名字,而无须将其作为参数传入,这使得类名可以在运行时决定;在上述最后两个重载方法中,参数 attributeName参数指明了 XML 元素的属性的名字,该属性包含了将要实例化的类的名字;
step1)添加创建对象的一条规则:digester.addObjectCreate("employee",null,"className");(属性名是 className);step2)传入XML 元素中的类名: <employee firstName="pacoson" lastName="xiao" className="mydiy.employee">;如果employee元素包含 className属性,那么该属性指定的值会用来作为待实例化的类的名字,如果没有包含 className属性,则会使用默认的类名;(干货——显然意思是说Emplyee类需要依赖 名为className的类对象)
public void addSetProperties(String pattern) {
addRule(pattern, new SetPropertiesRule());
}
public void addSetProperties( String pattern, String attributeName, String propertyName) {
addRule(pattern, new SetPropertiesRule(attributeName, propertyName));
}
public void addSetProperties(String pattern, String [] attributeNames, String [] propertyNames) {
addRule(pattern, new SetPropertiesRule(attributeNames, propertyNames));
}digester.addObjectCreate("employee", "mydiy.Employee");
digester.addSetProperties("employee");A1)上面的Digester有两个Rule 对象,分别用来创建对象和设置属性,他们都是通过employee模式触发的。而Rule对象按照其添加到Digester实例中的顺序逐个执行。A2)对于下面XMl 文档中的employee 元素(该元素匹配 employee模式): <employee firstName="pacoson", lastName="Xiao">;依据Digester的第一条rule,会创建 diy.Employee类的一个实例,依据第二条Rule,调用已经实例化的Employee.setFirstName() and Employee.setLastName(),分别传入pacoson 和 Xiao 来设置属性;
public void addCallMethod(String pattern, String methodName) {
addRule( pattern, new CallMethodRule(methodName));
}
public void addCallMethod(String pattern, String methodName, int paramCount) {
addRule(pattern, new CallMethodRule(methodName, paramCount));
}
public void addCallMethod(String pattern, String methodName, int paramCount, String paramTypes[]) {
addRule(pattern, new CallMethodRule(
methodName,
paramCount,
paramTypes));
}
public void addCallMethod(String pattern, String methodName,
int paramCount, Class paramTypes[]) {
addRule(pattern,
new CallMethodRule(
methodName,
paramCount,
paramTypes));
}5.4.1)addSetNext()方法:若栈中有两个对象,那么该方法会调用第1个对象的指定方法并将第2个对象作为参数传入该方法来创建第1个对象和第2个对象的关系;public void addSetNext(String pattern, String methodName) { addRule(pattern, new SetNextRule(methodName)); } public void addSetNext(String pattern, String methodName, String paramType) { addRule(pattern, new SetNextRule(methodName, paramType)); }对以上代码的分析(Analysis):参数pattern 指明了触发该规则的具体模式,参数methodName 是将要调用的第1个对象的方法的名称。模式是如下格式:firstObject/secondObject;
step1)创建两个对象;digester.addObjectCreate("employee", "mydiy.Employee"); digester.addObjectCreate("employee/office", "mydiy.Office");step2)创建对象间的关系:需要另外定义一条规则,使用 addSetNext()方法来建立关系(调用addOffice()方法建立关系):digetster.addSetNext("employee/office", 'addOffice');
public class Test01 {
public static void main(String[] args) {
String path = System.getProperty("user.dir") + File.separator + "src";
File file = new File(path, "employee1.xml");
Digester digester = new Digester();
// add rules (为模式 employee 添加3条规则)
digester.addObjectCreate("employee",
"com.tomcat.chapter15.digestertest.Employee");
digester.addSetProperties("employee");
digester.addCallMethod("employee", "printName");
try {
Employee employee = (Employee) digester.parse(file);
System.out.println("First name : " + employee.getFirstName());
System.out.println("Last name : " + employee.getLastName());
} catch (Exception e) {
e.printStackTrace();
}
}
}<?xml version="1.0" encoding="ISO-8859-1"?> <employee firstName="Brian" lastName="May"> </employee>
Creating Employee Setting firstName : Brian Setting lastName : May My name is Brian May First name : Brian Last name : May
step1)Digester类查看 employee 元素的开始标签,这会触发与 employee模式关联的3条规则,按照其被添加到 Digester 对象中的顺序逐个执行;step2)第一条规则用于创建Employee对象,调用构造函数,打印Creating Employee;step3)第二条规则设置 Employee对象的属性,在employee 元素中包含两个属性:分别是 firstName 和 lastName, 这会调用调用的set方法,打印 Setting firstName : Brian Setting lastName : May;step4)第三条规则调用 Employee.printName()方法,打印M y name is Brian May;
public class Test02 {
public static void main(String[] args) {
String path = System.getProperty("user.dir") + File.separator + "src";
File file = new File(path, "employee2.xml");
Digester digester = new Digester();
// add rules,添加规则(key)
digester.addObjectCreate("employee",
"com.tomcat.chapter15.digestertest.Employee");
digester.addSetProperties("employee");
digester.addObjectCreate("employee/office",
"com.tomcat.chapter15.digestertest.Office");
digester.addSetProperties("employee/office");
digester.addSetNext("employee/office", "addOffice");
digester.addObjectCreate("employee/office/address",
"com.tomcat.chapter15.digestertest.Address");
digester.addSetProperties("employee/office/address");
digester.addSetNext("employee/office/address", "setAddress");
try {
Employee employee = (Employee) digester.parse(file);
ArrayList offices = employee.getOffices();
Iterator iterator = offices.iterator();
System.out
.println("-------------------------------------------------");
while (iterator.hasNext()) {
Office office = (Office) iterator.next();
Address address = office.getAddress();
System.out.println(office.getDescription());
System.out.println("Address : " + address.getStreetNumber()
+ " " + address.getStreetName());
System.out.println("--------------------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}<?xml version="1.0" encoding="ISO-8859-1"?>
<employee firstName="Freddie" lastName="Mercury">
<office description="Headquarters">
<address streetName="Wellington Avenue" streetNumber="223"/>
</office>
<office description="Client site">
<address streetName="Downing Street" streetNumber="10"/>
</office>
</employee>Creating Employee Setting firstName : Freddie Setting lastName : Mercury ..Creating Office ..Setting office description : Headquarters ....Creating Address ....Setting streetName : Wellington Avenue ....Setting streetNumber : 223 ..Setting office address : ....223 Wellington Avenue Adding Office to this employee ..Creating Office ..Setting office description : Client site ....Creating Address ....Setting streetName : Downing Street ....Setting streetNumber : 10 ..Setting office address : ....10 Downing Street Adding Office to this employee ------------------------------------------------- Headquarters Address : 223 Wellington Avenue -------------------------------- Client site Address : 10 Downing Street --------------------------------
public void begin(Attributes attributes) throws Exception {
; // The default implementation does nothing
}
public void begin(String namespace, String name, Attributes attributes)
throws Exception {
begin(attributes);
}public void end() throws Exception {
; // The default implementation does nothing
}
public void end(String namespace, String name)
throws Exception {
end();
} public void addRule(String pattern, Rule rule) {
rule.setDigester(this);
getRules().add(pattern, rule);
}4)再次review Digester.addObjectCreate()方法的重载version:public void addObjectCreate(String pattern, String className) {
addRule(pattern, new ObjectCreateRule(className));
}
public void addObjectCreate(String pattern, Class clazz) {
addRule(pattern, new ObjectCreateRule(clazz));
}
public void addObjectCreate(String pattern, String className, String attributeName) {
addRule(pattern, new ObjectCreateRule(className, attributeName));
}
public void addObjectCreate(String pattern, String attributeName, Class clazz) {
addRule(pattern, new ObjectCreateRule(attributeName, clazz));
}A1)这4个重载方法都调用了addRule()方法,ObjectCreateRule类 是 Rule 类的子类,该类的实例都作为 addRule()方法的参数;A2)ObjectCreateRule.start()方法 和 ObjectCreateRule.end()方法的实现如下:public void begin(Attributes attributes) throws Exception { //org.apache.commons.digester.ObjectCreateRule.begin(). // Identify the name of the class to instantiate String realClassName = className; if (attributeName != null) { String value = attributes.getValue(attributeName); if (value != null) { realClassName = value; } } if (digester.log.isDebugEnabled()) { digester.log.debug("[ObjectCreateRule]{" + digester.match + "}New " + realClassName); } // Instantiate the new object and push it on the context stack Class clazz = digester.getClassLoader().loadClass(realClassName); Object instance = clazz.newInstance(); digester.push(instance); //highlight line. } public void end() throws Exception { Object top = digester.pop(); //highlight line. if (digester.log.isDebugEnabled()) { digester.log.debug("[ObjectCreateRule]{" + digester.match + "} Pop " + top.getClass().getName()); } }对以上代码的分析(Analysis):begin()方法的最后三行会创建Digester对象的一个实例,并将其压入到 Digester对象的内部栈中。end()方法 会将内部站的栈顶元素弹出;
2.1)addRuleInstance方法:将在当前RuleSet 中的Rule对象的集合作为该方法的参数添加到 Digester实例中;2.2)getNamespaceURI方法:返回将要应用在 RuleSet中所有Rule 对象的命名空间的URI;
public abstract class RuleSetBase implements RuleSet {
protected String namespaceURI = null;
public String getNamespaceURI() {
return (this.namespaceURI);
}
public abstract void addRuleInstances(Digester digester);
}4)测试用例public class Test03 {
public static void main(String[] args) {
String path = System.getProperty("user.dir") + File.separator + "src";
File file = new File(path, "employee2.xml");
Digester digester = new Digester();
digester.addRuleSet(new EmployeeRuleSet());
try {
Employee employee = (Employee) digester.parse(file);
ArrayList offices = employee.getOffices();
Iterator iterator = offices.iterator();
System.out
.println("-------------------------------------------------");
while (iterator.hasNext()) {
Office office = (Office) iterator.next();
Address address = office.getAddress();
System.out.println(office.getDescription());
System.out.println("Address : " + address.getStreetNumber()
+ " " + address.getStreetName());
System.out.println("--------------------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}public class SimpleContextConfig implements LifecycleListener {
public void lifecycleEvent(LifecycleEvent event) {
if (Lifecycle.START_EVENT.equals(event.getType())) {
Context context = (Context) event.getLifecycle();
context.setConfigured(true);
}
}
}4.1)默认的web.xml:位于 CATALINA_HOME/conf 目录中,其中定义并映射了很多默认的 servlet,配置了很多 MIME类型文件的映射,定义了默认的session超时时间,以及定义了欢迎文件的列表;4.2)应用程序的web.xml文件:位于 WEB-INF 目录中;
LifecycleListener listener = new ContextConfig();
((Lifecycle) context).addLifecycleListener(listener);7.1)在启动 StandardContext实例时,会触发以下事件(events):
event1)BEFORE_START_EVENT;event2)START_EVENT;event3)AFTER_START_EVENT;
7.2)当程序停止时,会触发以下事件:
event1)BEFORE_STOP_EVENT;event2)STOP_EVENT;event3)AFTER_STOP_EVENT;
public void lifecycleEvent(LifecycleEvent event) { //org.apache.catalina.startup.ContextConfig.lifecycleEvent().
// Identify the context we are associated with
try {
context = (Context) event.getLifecycle();
if (context instanceof StandardContext) {
int contextDebug = ((StandardContext) context).getDebug();
if (contextDebug > this.debug)
this.debug = contextDebug;
}
} catch (ClassCastException e) {
log(sm.getString("contextConfig.cce", event.getLifecycle()), e);
return;
}
// Process the event that has occurred
if (event.getType().equals(Lifecycle.START_EVENT))
start(); //highlight line.
else if (event.getType().equals(Lifecycle.STOP_EVENT))
stop(); //highlight line.
}private synchronized void start() { //org.apache.catalina.startup.ContextConfig.start().
if (debug > 0)
log(sm.getString("contextConfig.start"));
context.setConfigured(false);
ok = true;
// Set properties based on DefaultContext
Container container = context.getParent();
if( !context.getOverride() ) {
if( container instanceof Host ) {
((Host)container).importDefaultContext(context);
container = container.getParent();
}
if( container instanceof Engine ) {
((Engine)container).importDefaultContext(context);
}
}
// Process the default and application web.xml files
defaultConfig(); // highlight line.
applicationConfig(); // highlight line.
if (ok) {
validateSecurityRoles();
}
// Scan tag library descriptor files for additional listener classes
if (ok) {
try {
tldScan();
} catch (Exception e) {
log(e.getMessage(), e);
ok = false;
}
}
// Configure a certificates exposer valve, if required
if (ok)
certificatesConfig();
// Configure an authenticator if we need one
if (ok)
authenticatorConfig();
// Dump the contents of this pipeline if requested
if ((debug >= 1) && (context instanceof ContainerBase)) {
log("Pipline Configuration:");
Pipeline pipeline = ((ContainerBase) context).getPipeline();
Valve valves[] = null;
if (pipeline != null)
valves = pipeline.getValves();
if (valves != null) {
for (int i = 0; i < valves.length; i++) {
log(" " + valves[i].getInfo());
}
}
log("======================");
}
// Make our application available if no problems were encountered
if (ok)
context.setConfigured(true);
else {
log(sm.getString("contextConfig.unavailable"));
context.setConfigured(false);
}
} private void defaultConfig() { //org.apache.catalina.startup.ContextConfig.defaultConfig().
// Open the default web.xml file, if it exists
File file = new File(Constants.DefaultWebXml);
// public static final String DefaultWebXml = "conf/web.xml";
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 (锁定webDigester变量,并解析默认的 web.xml 文件)
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);
webDigester.push(null); // 解析结束.
} 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);
}
}
}
}private void applicationConfig() { //org.apache.catalina.startup.ContextConfig.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);
webDigester.push(null);
} 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);
}
}
}
}private static Digester webDigester = createWebDigester();
private static Digester createWebDigester() { //org.apache.catalina.startup.ContextConfig.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());
webDigester.addRuleSet(new WebRuleSet()); // highlight line.
return (webDigester);
}A1)createWebDigester()方法调用了变量webDigester的 addRuleSet()方法,传入了一个 org.apache.catalina.startup.WebRuleSet 类型的对象作为参数;A2)WebRuleSet 类是 org.apache.commons.digester.RuleSetBase的子类;public class WebRuleSet extends RuleSetBase { //org.apache.catalina.startup.WebRuleSetA3)org.apache.catalina.startup.WebRuleSet的定义代码见 文末,特别要注意其addRuleInstances()方法,其添加了很多规则集合;(干货——addRuleInstances()方法添加了很多规则集合)
public final class Bootstrap {
// invoke: http://localhost:8080/app1/Modern or
// http://localhost:8080/app2/Primitive
// note that we don't instantiate a Wrapper here,
// ContextConfig reads the WEB-INF/classes dir and loads all servlets.
public static void main(String[] args) {
System.setProperty("catalina.base", System.getProperty("user.dir"));
Connector connector = new HttpConnector();
Context context = new StandardContext();
// StandardContext's start method adds a default mapper
context.setPath("/app1");
context.setDocBase("app1");
LifecycleListener listener = new ContextConfig();
((Lifecycle) context).addLifecycleListener(listener);
Host host = new StandardHost();
host.addChild(context);
host.setName("localhost");
host.setAppBase("webapps");
Loader loader = new WebappLoader();
context.setLoader(loader);
connector.setContainer(host);
try {
connector.initialize();
((Lifecycle) connector).start();
((Lifecycle) host).start();
Container[] c = context.findChildren();
int length = c.length;
for (int i=0; i<length; i++) {
Container child = c[i];
System.out.println(child.getName());
}
// make the application wait until we press a key.
System.in.read();
((Lifecycle) host).stop();
}
catch (Exception e) {
e.printStackTrace();
}
}
} public static final String ApplicationWebXml = "/WEB-INF/web.xml";
public static final String DefaultWebXml = "conf/web.xml"; // both of them are defined in org.apache.catalina.startup.Constant;<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>Modern</servlet-name>
<servlet-class>ModernServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Primitive</servlet-name>
<servlet-class>PrimitiveServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Modern</servlet-name>
<url-pattern>/Modern</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Primitive</servlet-name>
<url-pattern>/Primitive</url-pattern>
</servlet-mapping>
</web-app>E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java -cp .;lib/servlet.jar;lib/catalina_4_1_24.jar;lib/catalina-5.5.4.jar;lib/naming-common. jar;lib/commons-collections.jar;lib/naming-resources.jar;lib/commons-digester.jar;lib/catalina.jar;lib/commons-logging.jar;lib/commons-beanutils.jar;E :\bench-cluster\cloud-data-preprocess\HowTomcatWoks\webroot com.tomcat.chapter15.startup.Bootstrap HttpConnector Opening server socket on all host IP addresses HttpConnector[8080] Starting background thread WebappLoader[/app1]: Deploying class repositories to work directory E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src\work\_\localhost\app1 WebappLoader[/app1]: Deploy class files /WEB-INF/classes to E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src\webapps\app1\WEB-INF\classes ContextConfig[/app1]: Missing default web.xml, using application web.xml only StandardManager[/app1]: Seeding random number generator class java.security.SecureRandom StandardManager[/app1]: Seeding of random number generator has been completed Primitive Modern StandardHost[localhost]: MAPPING configuration error for request URI /Modern/app1/Modern StandardHost[localhost]: MAPPING configuration error for request URI /favicon.ico ModernServlet -- init StandardHost[localhost]: MAPPING configuration error for request URI /favicon.ico
public class WebRuleSet extends RuleSetBase { //org.apache.catalina.startup.WebRuleSet
protected String prefix = null;
public WebRuleSet() {
this("");
}
public WebRuleSet(String prefix) {
super();
this.namespaceURI = null;
this.prefix = prefix;
}
public void addRuleInstances(Digester digester) { // highlight.
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/ejb-local-ref",
"org.apache.catalina.deploy.ContextLocalEjb");
digester.addSetNext(prefix + "web-app/ejb-local-ref",
"addLocalEjb",
"org.apache.catalina.deploy.ContextLocalEjb");
digester.addCallMethod(prefix + "web-app/ejb-local-ref/description",
"setDescription", 0);
digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-link",
"setLink", 0);
digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-ref-name",
"setName", 0);
digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-ref-type",
"setType", 0);
digester.addCallMethod(prefix + "web-app/ejb-local-ref/local",
"setLocal", 0);
digester.addCallMethod(prefix + "web-app/ejb-local-ref/local-home",
"setHome", 0);
digester.addObjectCreate(prefix + "web-app/ejb-ref",
"org.apache.catalina.deploy.ContextEjb");
digester.addSetNext(prefix + "web-app/ejb-ref",
"addEjb",
"org.apache.catalina.deploy.ContextEjb");
digester.addCallMethod(prefix + "web-app/ejb-ref/description",
"setDescription", 0);
digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-link",
"setLink", 0);
digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-ref-name",
"setName", 0);
digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-ref-type",
"setType", 0);
digester.addCallMethod(prefix + "web-app/ejb-ref/home",
"setHome", 0);
digester.addCallMethod(prefix + "web-app/ejb-ref/remote",
"setRemote", 0);
digester.addObjectCreate(prefix + "web-app/env-entry",
"org.apache.catalina.deploy.ContextEnvironment");
digester.addSetNext(prefix + "web-app/env-entry",
"addEnvironment",
"org.apache.catalina.deploy.ContextEnvironment");
digester.addCallMethod(prefix + "web-app/env-entry/description",
"setDescription", 0);
digester.addCallMethod(prefix + "web-app/env-entry/env-entry-name",
"setName", 0);
digester.addCallMethod(prefix + "web-app/env-entry/env-entry-type",
"setType", 0);
digester.addCallMethod(prefix + "web-app/env-entry/env-entry-value",
"setValue", 0);
digester.addObjectCreate(prefix + "web-app/error-page",
"org.apache.catalina.deploy.ErrorPage");
digester.addSetNext(prefix + "web-app/error-page",
"addErrorPage",
"org.apache.catalina.deploy.ErrorPage");
digester.addCallMethod(prefix + "web-app/error-page/error-code",
"setErrorCode", 0);
digester.addCallMethod(prefix + "web-app/error-page/exception-type",
"setExceptionType", 0);
digester.addCallMethod(prefix + "web-app/error-page/location",
"setLocation", 0);
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.addObjectCreate(prefix + "web-app/login-config",
"org.apache.catalina.deploy.LoginConfig");
digester.addSetNext(prefix + "web-app/login-config",
"setLoginConfig",
"org.apache.catalina.deploy.LoginConfig");
digester.addCallMethod(prefix + "web-app/login-config/auth-method",
"setAuthMethod", 0);
digester.addCallMethod(prefix + "web-app/login-config/realm-name",
"setRealmName", 0);
digester.addCallMethod(prefix + "web-app/login-config/form-login-config/form-error-page",
"setErrorPage", 0);
digester.addCallMethod(prefix + "web-app/login-config/form-login-config/form-login-page",
"setLoginPage", 0);
digester.addCallMethod(prefix + "web-app/mime-mapping",
"addMimeMapping", 2);
digester.addCallParam(prefix + "web-app/mime-mapping/extension", 0);
digester.addCallParam(prefix + "web-app/mime-mapping/mime-type", 1);
digester.addCallMethod(prefix + "web-app/resource-env-ref",
"addResourceEnvRef", 2);
digester.addCallParam(prefix + "web-app/resource-env-ref/resource-env-ref-name", 0);
digester.addCallParam(prefix + "web-app/resource-env-ref/resource-env-ref-type", 1);
digester.addObjectCreate(prefix + "web-app/resource-ref",
"org.apache.catalina.deploy.ContextResource");
digester.addSetNext(prefix + "web-app/resource-ref",
"addResource",
"org.apache.catalina.deploy.ContextResource");
digester.addCallMethod(prefix + "web-app/resource-ref/description",
"setDescription", 0);
digester.addCallMethod(prefix + "web-app/resource-ref/res-auth",
"setAuth", 0);
digester.addCallMethod(prefix + "web-app/resource-ref/res-ref-name",
"setName", 0);
digester.addCallMethod(prefix + "web-app/resource-ref/res-sharing-scope",
"setScope", 0);
digester.addCallMethod(prefix + "web-app/resource-ref/res-type",
"setType", 0);
digester.addObjectCreate(prefix + "web-app/security-constraint",
"org.apache.catalina.deploy.SecurityConstraint");
digester.addSetNext(prefix + "web-app/security-constraint",
"addConstraint",
"org.apache.catalina.deploy.SecurityConstraint");
digester.addRule(prefix + "web-app/security-constraint/auth-constraint",
new SetAuthConstraintRule(digester));
digester.addCallMethod(prefix + "web-app/security-constraint/auth-constraint/role-name",
"addAuthRole", 0);
digester.addCallMethod(prefix + "web-app/security-constraint/display-name",
"setDisplayName", 0);
digester.addCallMethod(prefix + "web-app/security-constraint/user-data-constraint/transport-guarantee",
"setUserConstraint", 0);
digester.addObjectCreate(prefix + "web-app/security-constraint/web-resource-collection",
"org.apache.catalina.deploy.SecurityCollection");
digester.addSetNext(prefix + "web-app/security-constraint/web-resource-collection",
"addCollection",
"org.apache.catalina.deploy.SecurityCollection");
digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/http-method",
"addMethod", 0);
digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/url-pattern",
"addPattern", 0);
digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/web-resource-name",
"setName", 0);
digester.addCallMethod(prefix + "web-app/security-role/role-name",
"addSecurityRole", 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",
"setServletClass", 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
/**
* A Rule that calls the <code>setAuthConstraint(true)</code> method of
* the top item on the stack, which must be of type
* <code>org.apache.catalina.deploy.SecurityConstraint</code>.
*/
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)");
}
}
/**
* Class that calls <code>setDistributable(true)</code> for the top object
* on the stack, which must be a <code>org.apache.catalina.Context</code>.
*/
final class SetDistributableRule extends Rule {
public SetDistributableRule(Digester digester) {
super(digester);
}
public void begin(Attributes attributes) throws Exception {
Context context = (Context) digester.peek();
context.setDistributable(true);
if (digester.getDebug() > 0)
digester.log(context.getClass().getName() +
".setDistributable( true)");
}
}
/**
* Class that calls a property setter for the top object on the stack,
* passing the public ID of the entity we are currently processing.
*/
final class SetPublicIdRule extends Rule {
public SetPublicIdRule(Digester digester, String method) {
super(digester);
this.method = method;
}
private String method = null;
public void begin(Attributes attributes) throws Exception {
Context context = (Context) digester.peek(digester.getCount() - 1);
Object top = digester.peek();
Class paramClasses[] = new Class[1];
paramClasses[0] = "String".getClass();
String paramValues[] = new String[1];
paramValues[0] = digester.getPublicId();
Method m = null;
try {
m = top.getClass().getMethod(method, paramClasses);
} catch (NoSuchMethodException e) {
digester.log("Can't find method " + method + " in " + top +
" CLASS " + top.getClass());
return;
}
m.invoke(top, paramValues);
if (digester.getDebug() >= 1)
digester.log("" + top.getClass().getName() + "." + method +
"(" + paramValues[0] + ")");
}
}
/**
* A Rule that calls the factory method on the specified Context to
* create the object that is to be added to the stack.
*/
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());
}
}标签:
原文地址:http://blog.csdn.net/pacosonswjtu/article/details/51477673