撇开tomcat作为servlet容器的行为。它和apache、nginx的功能大致都能对应上。例如以nginx为例,以下是nginx提供web服务时的配置结构:
server { listen PORT; server_name ; # 对应于<host name=www.a.com> location / { # 对应于context path="" root html; # 对应于docBase } location /xuexi { # 对应于context path="/xuexi" root html/xuexi; } }connetcor组件类似于nginx的listen指令。host容器类似于nginx的server指令,host容器中的name属性相当于nginx的server_name指令。engine组件则没有对应配置项,不过在nginx同样有engine的功能,例如默认的虚拟主机,分析URL来判断请求交给哪个虚拟主机处理等。context容器相当于location指令,context容器的path属性相当于location的uri匹配路径,docBase相当于location的中的root指令,即DocumentRoot。
tomcat作为简单的web服务程序大致如此,但它的核心毕竟是处理servlet和jsp,它必须得管理好每个webapp。因此,对于tomcat来说,必须要掌握部署webapp的方式。在tomcat上部署webapp时,必须要理解context的概念。对于tomcat而言,每个context都应该算是一个webapp,其路径由docBase决定,该目录存放的是归档的war文件或未归档的webapp相关文件,而host容器中的appBase则是虚拟主机整理webapp的地方,一个appBase下可以有多个webapp,即多个context。
3. tomcat的appBase和docBase详细说明这两货虽然意义很明确,但"潜规则"很严重。以下面的配置为例。
<host name= appBase=/www/a > <context path="" docBase=/www/a /> <context path="/xuexi" docBase=/www/a/xuexi /> </host>appBase是虚拟主机存放webapp的目录,它可以是相对路径,也可以是绝对路径。如果是相对路径,则相对于$CATALINA_HOME,严格并准确地说是$CATALINA_BASE。
path是URI的匹配路径,相当于nginx的location后的路径。tomcat要求每个虚拟主机必须配置一个空字符串的path,该条context作为URI无法被明确匹配时的默认context,它相当于nginx中location / {}的作用。
docBase则是每个webapp的存放目录(或者是已归档的war文件),它可以是相对路径,也可以是绝对路径,提供相对路径时它相对于appBase。该目录一般在appBase的目录下,但并不规定一定要放在appBase下。对于web服务来说,它相当于nginx的root指令,但对于webapp来说,一个context就相当于一个webapp,而docBase正是webapp的路径。
"潜规则"在于默认的context如何提供。有以下几种情况:
明确定义了<context path="" docBase=webappPATH>,此时默认context的处理路径为webappPATH。
明确定义了<context path="">,但却没给定docBase属性,此时该默认context处理路径为appBase/ROOT目录,注意ROOT为大写。
完全没有定义path=""的context时,即host容器中没有明确的path="",此时将隐式定义一个默认context,处理路径为appBase/ROOT目录。
定义了path但没有定义docBase属性时,docBase将根据path推断出它的路径。推断的规则如下:(注:此时推断的不是默认context,而是对应context的docbase)
context path context name 推断出的docBase路径 -------------------------------------------------- /foo /foo foo /foo/bar /foo/bar foo/bar Empty String Empty String ROOT显然,没有给定path=""或缺少docbase时,都以ROOT作为目录。以下是几个定义示例:
# 虚拟主机中没有定义任何context,将以appBase下的ROOT作为默认处理路径 <Host appBase="webapps"> </Host> # 没有定义path=""的context,但定义了path非空的context,也将以ROOT作为默认处理路径 # 如果下面的Context容器中省略docBase属性,则推断出该context的docBase路径为appBase/xuexi <Host appBase="webapps"> <Context path="/xuexi" docBase="webappPATH" /> </Host> # 某个context定义了path="",该context将作为默认context # 但该默认context如果没有定义docBase,将推断出其docBase路径为appBase/ROOT <Host appBase="webapps"> <Context path="" docBase="webappPATH" /> </Host> # 某个context定义了path="",该context将作为默认context # 下面的默认context明确定义了docBase <Host appBase="webapps"> <Context path="" docBase="webappPATH" /> </Host> 4. webapp体系结构webapp有特定的组织格式,是一种层次型目录结构,通常包含了servlet代码文件、jsp页面文件、类文件、部署描述符文件等等。