tomcat appBase docBase webapps ,war包自动生成ROOT目录 ,tomcat部署的应用启动两次

需求

tomcat下,进行war包部署,假设war包名为 test.war,启动tomcat后,webapps中会有ROOT,test两目录和test.war文件。访问test应用内容,需加上应用名test,如 localhost:8080/test/。
目标是想不自动生成ROOT目录,且访问test应用不需加应用名test,就如访问ROOT中的应用一样。

原项目server.xml关键配置如下:

      ...
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Context path="" docBase="/opt/tomcat/webapps/test" debug="0"  reloadable="true" />
      ...

估计也是前面人员从网上下的配置,看样子也没自己弄清楚,反正能跑起来,就敷衍了事了。
至于这个debug=“0” ,猜想是要关掉debug功能和debug信息。我在tomcat8、7的官档里context部分都没查到有这个属性选项,可能是再之前版本的吧。
reloadable是基于 /WEB-INF/classes/ and /WEB-INF/lib两个目录的类发生改变则自动重载,不建议产线使用。

资料

https://tomcat.apache.org/tomcat-8.5-doc/config/host.html
appBase
The Application Base directory for this virtual host. This is the pathname of a directory that may contain web applications to be deployed on this virtual host. You may specify an absolute pathname, or a pathname that is relative to the $CATALINA_BASE directory. See Automatic Application Deployment for more information on automatic recognition and deployment of web applications. If not specified, the default of webapps will be used.

deployOnStartup
This flag value indicates if web applications from this host should be automatically deployed when Tomcat starts. The flag’s value defaults to true. See Automatic Application Deployment for more information.

autoDeploy
This flag value indicates if Tomcat should check periodically for new or updated web applications while Tomcat is running. If true, Tomcat periodically checks the appBase and xmlBase directories and deploys any new web applications or context XML descriptors found. Updated web applications or context XML descriptors will trigger a reload of the web application. The flag’s value defaults to true. See Automatic Application Deployment for more information.

unpackWARs
Set to true if you want web applications that are placed in the appBase directory as web application archive (WAR) files to be unpacked into a corresponding disk directory structure, false to run such web applications directly from a WAR file. See Automatic Application Deployment for more information.

https://tomcat.apache.org/tomcat-8.5-doc/config/context.html
docBase
The Document Base (also known as the Context Root) directory for this web application, or the pathname to the web application archive file (if this web application is being executed directly from the WAR file). You may specify an absolute pathname for this directory or WAR file, or a pathname that is relative to the appBase directory of the owning Host.

The value of this field must not be set unless the Context element is defined in server.xml or the docBase is not located under the Host’s appBase.

If a symbolic link is used for docBase then changes to the symbolic link will only be effective after a Tomcat restart or by undeploying and redeploying the context. A context reload is not sufficient.

path
The context path of this web application, which is matched against the beginning of each request URI to select the appropriate web application for processing. All of the context paths within a particular Host must be unique. If you specify a context path of an empty string (""), you are defining the default web application for this Host, which will process all requests not assigned to other Contexts.

This attribute must only be used when statically defining a Context in server.xml. In all other circumstances, the path will be inferred from the filenames used for either the .xml context file or the docBase.

Even when statically defining a Context in server.xml, this attribute must not be set unless either the docBase is not located under the Host’s appBase or both deployOnStartup and autoDeploy are false. If this rule is not followed, double deployment is likely to result.

reloadable
Set to true if you want Catalina to monitor classes in /WEB-INF/classes/ and /WEB-INF/lib for changes, and automatically reload the web application if a change is detected. This feature is very useful during application development, but it requires significant runtime overhead and is not recommended for use on deployed production applications. That’s why the default setting for this attribute is false. You can use the Manager web application, however, to trigger reloads of deployed applications on demand.

https://tomcat.apache.org/tomcat-8.5-doc/config/context.html#Naming

If no version is specified then the context name is always the same as the context path. If the context path is the empty string then the base name will be ROOT (always in upper case) otherwise the base name will be the context path with the leading ‘/’ removed and any remaining ‘/’ characters replaced with ‘#’.

说明了<Context /> 中 path的设置跟appBase下的ROOT目录的关系,path为空,则默认ROOT。
如果将path设置为test,则在appBase下不会自动生成ROOT目录,会将war解压生成test目录。

If you want to deploy a WAR file or a directory using a context path that is not related to the base file name then one of the following options must be used to prevent double-deployment:

  • Disable autoDeploy and deployOnStartup and define all Contexts in server.xml
  • Locate the WAR and/or directory outside of the Host’s appBase and use a context.xml file with a docBase attribute to define it.

分析

来解析一下webapps下为什么会出现ROOT和test两个目录,
Context段中,path为空,应用名称默认为ROOT,tomcat启动时将appBase下的war包解压放入ROOT目录,
Host段中,又会重新解压一次,生成test目录。
这个可以在catalina.out日志中看到,也可以tail日志的同时查看webapps目录,会发现先出现的是ROOT目录。

也看到有文章说,将appBase置空,像如下配置,就可以不生成ROOT目录,其实是错的,appBase置空后,ROOT不是不生成了,而是跑到CATALINA_HOME的目录下去了,docBase指定的路径其实还是在appBase目录之下的,原理是在appBase下的war包(包括子目录)会根据 unpackWARs=“true” autoDeploy=“true” 还一个默认的deployOnStartup,三个选项进行自动解压,path为空,则自动解压到ROOT目录。如果appBase目录下这一级有war包,会自动再次解压到以war包名的为目录名的目录,其实也就是上述的为什么会出现ROOT和test两个目录,和同一个应用启动两次的根本原因。

      ...
      <Host name="localhost"  appBase=""
            unpackWARs="true" autoDeploy="true">
        <Context path="" docBase="/opt/tomcat/webapps/test" reloadable="true" />
      ...

上面有点绕,看起来可能有些晕。
还可以通过如下配置进行测试来说明问题:

      ...
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Context path="" docBase="/opt/tomcat/webapps/abc/test" reloadable="true" />
      ...

将test.war包放入/opt/tomcat/webapps/abc目录中,启动tomcat后,你会发现,不会重复启动两次test应用,而/opt/tomcat/webapps下只会自动生成ROOT目录,/opt/tomcat/webapps/abc/目录中的war包并没有在/opt/tomcat/webapps/abc/目录或者/opt/tomccat/webapps/目录中再解压到test文件夹。

结论

其实以上分析推论可以从tomcat源码进行论证,可惜我不会java,所以,如有分析错误,请指正!谢谢

无法通过配置直接实现需求,单应用可以将war包名称改为ROOT.war,直接解压为ROOT。
其他应用名称的war包部署后必须在url访问时加上应用名称。

附URL的组成格式

// 下面字串之间是无空格的,方便看清,所以加上了一些空格
protocol :// hostname [:port] /path/ [;parameters] [?query] #fragment

方括号是可选项

  • protocol 协议,常用的协议是http
  • hostname 主机地址,可以是域名,也可以是IP地址
  • port 端口 http协议默认端口是:80端口,如果不写默认就是:80端口
  • path 路径 网络资源在服务器中的指定路径
  • parameter 参数 如果要向服务器传入参数,在这部分输入
  • query 查询字符串 如果需要从服务器那里查询内容,在这里编辑
  • fragment 片段 网页中可能会分为不同的片段,如果想访问网页后直接到达指定位置,可以在这部分设置

附server.xml的参考

<?xml version='1.0' encoding='utf-8'?>

<!--
Server是一个顶级组件,代表了一个Tomcat实例,一个JVM进程中只能有一个Server实例。
Tomcat提供了一个实现了 org.apache.catalina.Server接口的 org.apache.catalina.core.StandardServer默认类,读取Server元素配置。

Server是配置文件中的最外层元素,支持以下属性:
      className:指定要使用的实现类(必须实现org.apache.catalina.Server接口)名称。如果不指定,默认使用标准实现类StandardServer。
      address:等待shutdown命令的服务器IP地址,默认是localhost。
      port:等待shutdown命令的监听端口,如果设置为-1,表示关闭shutdown端口。
      shutdown:指定终止Tomcat服务器运行时,发给Tomcat服务器的shutdown监听端口的字符串.该属性必须设置 。
-->
<Server port="8005" shutdown="SHUTDOWN">
    <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
    <Listener className="org.apache.catalina.core.JasperListener"/>
    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

    <!--定义的全局JNDI资源-->
    <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml"/>
    </GlobalNamingResources>

    <!--Server元素中可以有一个或多个Service,每个Service关联了多个Connector和一个Engine。
    Service支持两个属性:
        className:指定要使用的实现类(必须实现org.apache.catalina.Service接口)名称。如果不指定,默认使用标准实现类StandardService。
        name:Service的名称,在同一个Server元素中必须唯一,默认是Catalina。
    -->
    <Service name="Catalina">

        <!--Connector负责处理请求监听,一个Connector与一个TCP端口绑定,接受请求并将请求封装成Request和Response,Service中默认包含两个Connector。
            Connector支持四个属性:
                port:属性指定监听端口,默认8080端口,可修改为1024-65535间的任意一个端口
                protocol:支持协议
                connectionTimeout:定义连接器等待时间,默认20秒
                redirectPort:SSL请求会重定向到8443端口
        -->
        <!--HTTP/1.1:处理HTTP请求,此连接器使Tomcat可以作为HTTP服务器使用。-->
        <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>
        <!--AJP/1.3:Apache JServ 协议处理Tomcat与Apache之间的通信。Tomcat核心功能是解析Servlet,html和图片解析功能相对其他HTTP服务器较弱(如Apache HTTP Server),所以,一般都是集成使用,Apache处理静态页面请求,Tomcat处理Servlet/JSP请求。-->
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>

        <!--Container负责处理请求处理,有四个子容器:Engine、Host、Context和Wrapper,他们之间是父子包含关系。-->
        <!--一个Service只有一个Engine,表示整个Servlet引擎,其主要作用是执行业务逻辑;从HTTP Connector接收HTTP请求,并且会根据主机名/IP地址交由相应的主机处理请求。-->
        <Engine name="Catalina" defaultHost="localhost">
            <Realm className="org.apache.catalina.realm.LockOutRealm">
                <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
            </Realm>

            <!--Host,代表一个站点,也可以叫虚拟主机,一个Engine下面可以包含一个或者多个Host,即一个Tomcat实例可以配置多个虚拟主机-->
                <!--appBase:定义了应用程序的根目录,默认是webapps-->
                <!--unpackWARS:定义了是否解压webapps中的WAR文件,如果指定为“false”,会从WAR文件直接运行程序,执行较慢-->
                <!--autoDeploy:把应用程序直接拖到webapps目录下,是否自动运行-->
            <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
                <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b"/>
                <!--
                Context,代表一个应用程序
                    path:访问项目时的URL,加在localhost:8080后
                    docBase:path对应的项目目录
                    reloadable:监视 /WEB-INF/classes/ 和 /WEB-INF/lib目录中的类文件,更改后自动重载应用程序,
                    生成环境不建议使用,默认为“false”
                -->
                <Context path="/image" docBase="/opt/file/img" reloadable="false"></Context>
                <!--Wrapper针对的是每个具体的servlet-->
            </Host>
        </Engine>
    </Service>
</Server>


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值