Tomcat学习之Host
时间:2014-12-30 13:18 来源:linux.it.net.cn 作者:IT
引言
tomcat中一个Host代表一个虚拟主机,一个虚拟主机上可以有多个应用。Host的默认实现是StandardHost,它的pipeline有两个阀门:ErrorReportValve和StandardHostValve。前者负责选择context来处理用户请求,后者负责处理错误信息。本文主要讲解host容器部署web应用的过程以及它的常用配置项。
部署
所有与部署有关的方法都在类HostConfig中,包括目录的创建,资源的检查、应用部署等操作。其中应用部署是在deployApps中完成的
-
protected void deployApps() {
-
-
File appBase = appBase();
-
File configBase = configBase();
-
String[] filteredAppPaths = filterAppPaths(appBase.list());
-
// Deploy XML descriptors from configBase
-
deployDescriptors(configBase, configBase.list());
-
// Deploy WARs
-
deployWARs(appBase, filteredAppPaths);
-
// Deploy expanded folders
-
deployDirectories(appBase, filteredAppPaths);
-
-
}
Tomcat应用部署由三部分组成:1、部署描述符;2、部署WAR包;3、部署目录
部署描述符
首先获取${TOMCAT_HOME}\conf\Catalina\localhos目录下的所有xml文件,然后调用deployDescriptor方法一个一个部署,来看看deployDescriptor方法的实现
-
protected void deployDescriptor(ContextName cn, File contextXml) {
-
...
-
DeployedApplication deployedApp = new DeployedApplication(cn.getName());
-
...
-
deployedApp.redeployResources.put(contextXml.getAbsolutePath(),Long.valueOf(contextXml.lastModified()));
-
deployedApp.redeployResources.put(docBase.getAbsolutePath(),Long.valueOf(docBase.lastModified()));
-
deployedApp.reloadResources.put(resource.getAbsolutePath(), Long.valueOf(resource.lastModified()));
-
-
// Add the global redeploy resources (which are never deleted) at
-
// the end so they don't interfere with the deletion process
-
addGlobalRedeployResources(deployedApp);
-
...
-
deployed.put(context.getName(), deployedApp);
-
}
其实就做了几件事:
1、创建Context,因为一个文件就代表一个context,这里并没有展示有关context的代码
2、封装deployedApp,将代表context的xml文件路径和docBase指向的目录加入redeployResources中,将web.xml文件加入reloadResources中
3、最后将应用名与应用加入deployed这个map文件中,这个map代表被部署的应用。
部署WAR包
首先获取${TOMCAT_HOME}\webapps目录下的所有war包,然后调用deployWAR方法一个一个部署,具体做了以下几件事:
1、如果${appname}/META-INF/context.xml文件存在,利用digester将其解析为一个context,如果不存在,则创建org.apache.catalina.core.StandardContext实例;
2、为这个context设置一些属性,比如name,path,DocBase等;
3、然后做了部署描述符的后两步,封装deployedApp,并将其加入map中
第一步把context加入host时会做解包操作,具体的解包操作是在类ExpandWar的expand方法中完成的
-
while (jarEntries.hasMoreElements()) {
-
JarEntry jarEntry = jarEntries.nextElement();
-
String name = jarEntry.getName();
-
File expandedFile = new File(docBase, name);
-
-
int last = name.lastIndexOf('/');
-
if (last >= 0) {
-
File parent = new File(docBase, name.substring(0, last));
-
if (!parent.mkdirs() && !parent.isDirectory()) {
-
throw new IOException(
-
sm.getString("expandWar.createFailed", parent));
-
}
-
}
-
if (name.endsWith("/")) {
-
continue;
-
}
-
expand(input, expandedFile);
-
}
对于'/'结尾的是目录直接创建目录,不是以‘/’结尾的先创建空文件,然后调用expand方法向文件中写数据
-
private static void expand(InputStream input, File file)
-
throws IOException {
-
BufferedOutputStream output = null;
-
try {
-
output =
-
new BufferedOutputStream(new FileOutputStream(file));
-
byte buffer[] = new byte[2048];
-
while (true) {
-
int n = input.read(buffer);
-
if (n <= 0)
-
break;
-
output.write(buffer, 0, n);
-
}
-
} finally {
-
if (output != null) {
-
try {
-
output.close();
-
} catch (IOException e) {
-
// Ignore
-
}
-
}
-
}
-
}
部署目录和部署war文件类似,只是不需要解包操作。
配置
Host元素中有以下属性,下面分别讲解:
appBase:虚拟主机下应用的基准目录,可以是一个绝对路径,也可以是一个相对路径(相对于${CATALINA_BASE}),如果没有配置,默认为webapps.
xmlBase:部署描述文件的基准目录,可以是一个绝对路径,也可以是一个相对路径(相对于${CATALINA_BASE}),默认为${TOMCAT_HOME}\server\localhost
createDirs:设置为true,会在tomcat启动时创建appBase和xmlBase所指定的目录,这个值默认为true.如果这个值为true,且在创建目录的过程中报错会在控制台上打印错误信息,但不会导致应用挂掉
autoDeploy:默认为true,会定期地检查appBase和xmlBase中的文件变化,会导致一个web应用重新加载
deployOnStartup:默认为true,指示web应用启动时会自动部署xmlBase目录下的应用
Host的标准实现类StandardHost还支持以下属性:
copyXML:默认为false,如果为true,/META-INF/context.xml文件将会被拷贝到xmlBase中,xml文件名为应用名.如果这样做,tomcat会一直用xmlBase中的xml文件,即使/META-INF/context.xml文件更新。
deployXML:默认为true,会解析/META-INF/context.xml文件。如果为false会忽略/META-INF/context.xml文件
unpackWARs:默认为true,appBase目录下的war包会被解包,appBase外的war包不会解包
如果使用的是标准的HOST实现,在TOMCAT启动的时候(deployOnStartup=true)以下行为会自动触发:
1、xmlBase目录(默认为$CATALINA_BASE/conf/[engine_name]/[host_name])下面的xml文件代表一个上下文描述符,每个xml文件代表一个web应用,这些web应用会优先部署。Context元素的docBase属性为对应war包的名字。
2、appBase中的其他war包,由于没有对应的context.xml没有被优先部署,并不意味着这些war不会被部署,只能说不会被优先部署。war包的上下文路径为‘/war包的名字’(没有后缀),这里有个意外,ROOT.war对应的上下文路径为‘/’,多级context可以用#来定义,如foo#bar.war的上下文路径为‘/foo/bar’。
如果unpackWARs属性设置为true,在tomcat启动的时候会解压war包。注意:如果在tomcat停止时你修改了war包,确保删除解压出来的目录然后再重启tomcat,以便在重启时新修改的war包会被解压。如果copyXML属性为true(默认为false),那么会检查每个war包下/META-INF/context.xml文件是否存在,如果存在会将其拷贝到xmlBase中并重命名为war包的名字。
3、appBase中的其他子目录,由于没有对应的context.xml也没有被优先部署,并不意味着这些war不会被部署。这些目录的上下文路径为‘/目录名’,如果目录名为ROOT,上下文路径为‘/’,foo#bar目录的上下文路径为‘/foo/bar’。如果copyXML属性为true(默认为false),那么会检查每个目录下/META-INF/context.xml文件是否存在,如果存在会将其拷贝到xmkBase中并重命名为war的名字。
(责任编辑:IT)
引言tomcat中一个Host代表一个虚拟主机,一个虚拟主机上可以有多个应用。Host的默认实现是StandardHost,它的pipeline有两个阀门:ErrorReportValve和StandardHostValve。前者负责选择context来处理用户请求,后者负责处理错误信息。本文主要讲解host容器部署web应用的过程以及它的常用配置项。 部署
所有与部署有关的方法都在类HostConfig中,包括目录的创建,资源的检查、应用部署等操作。其中应用部署是在deployApps中完成的
部署描述符首先获取${TOMCAT_HOME}\conf\Catalina\localhos目录下的所有xml文件,然后调用deployDescriptor方法一个一个部署,来看看deployDescriptor方法的实现
1、创建Context,因为一个文件就代表一个context,这里并没有展示有关context的代码
2、封装deployedApp,将代表context的xml文件路径和docBase指向的目录加入redeployResources中,将web.xml文件加入reloadResources中
3、最后将应用名与应用加入deployed这个map文件中,这个map代表被部署的应用。
部署WAR包
首先获取${TOMCAT_HOME}\webapps目录下的所有war包,然后调用deployWAR方法一个一个部署,具体做了以下几件事:
1、如果${appname}/META-INF/context.xml文件存在,利用digester将其解析为一个context,如果不存在,则创建org.apache.catalina.core.StandardContext实例;
2、为这个context设置一些属性,比如name,path,DocBase等;
3、然后做了部署描述符的后两步,封装deployedApp,并将其加入map中
第一步把context加入host时会做解包操作,具体的解包操作是在类ExpandWar的expand方法中完成的
部署目录和部署war文件类似,只是不需要解包操作。
配置
Host元素中有以下属性,下面分别讲解:
appBase:虚拟主机下应用的基准目录,可以是一个绝对路径,也可以是一个相对路径(相对于${CATALINA_BASE}),如果没有配置,默认为webapps. xmlBase:部署描述文件的基准目录,可以是一个绝对路径,也可以是一个相对路径(相对于${CATALINA_BASE}),默认为${TOMCAT_HOME}\server\localhost createDirs:设置为true,会在tomcat启动时创建appBase和xmlBase所指定的目录,这个值默认为true.如果这个值为true,且在创建目录的过程中报错会在控制台上打印错误信息,但不会导致应用挂掉 autoDeploy:默认为true,会定期地检查appBase和xmlBase中的文件变化,会导致一个web应用重新加载 deployOnStartup:默认为true,指示web应用启动时会自动部署xmlBase目录下的应用 Host的标准实现类StandardHost还支持以下属性: copyXML:默认为false,如果为true,/META-INF/context.xml文件将会被拷贝到xmlBase中,xml文件名为应用名.如果这样做,tomcat会一直用xmlBase中的xml文件,即使/META-INF/context.xml文件更新。 deployXML:默认为true,会解析/META-INF/context.xml文件。如果为false会忽略/META-INF/context.xml文件 unpackWARs:默认为true,appBase目录下的war包会被解包,appBase外的war包不会解包
如果使用的是标准的HOST实现,在TOMCAT启动的时候(deployOnStartup=true)以下行为会自动触发:
1、xmlBase目录(默认为$CATALINA_BASE/conf/[engine_name]/[host_name])下面的xml文件代表一个上下文描述符,每个xml文件代表一个web应用,这些web应用会优先部署。Context元素的docBase属性为对应war包的名字。 2、appBase中的其他war包,由于没有对应的context.xml没有被优先部署,并不意味着这些war不会被部署,只能说不会被优先部署。war包的上下文路径为‘/war包的名字’(没有后缀),这里有个意外,ROOT.war对应的上下文路径为‘/’,多级context可以用#来定义,如foo#bar.war的上下文路径为‘/foo/bar’。
如果unpackWARs属性设置为true,在tomcat启动的时候会解压war包。注意:如果在tomcat停止时你修改了war包,确保删除解压出来的目录然后再重启tomcat,以便在重启时新修改的war包会被解压。如果copyXML属性为true(默认为false),那么会检查每个war包下/META-INF/context.xml文件是否存在,如果存在会将其拷贝到xmlBase中并重命名为war包的名字。
3、appBase中的其他子目录,由于没有对应的context.xml也没有被优先部署,并不意味着这些war不会被部署。这些目录的上下文路径为‘/目录名’,如果目录名为ROOT,上下文路径为‘/’,foo#bar目录的上下文路径为‘/foo/bar’。如果copyXML属性为true(默认为false),那么会检查每个目录下/META-INF/context.xml文件是否存在,如果存在会将其拷贝到xmkBase中并重命名为war的名字。
|