Hey, Nice to meet You. 

必有过人之节.人情有所不能忍者,匹夫见辱,拔剑而起,挺身而斗,此不足为勇也,天下有大勇者,猝然临之而不惊,无故加之而不怒.此其所挟持者甚大,而其志甚远也.          ☆☆☆所谓豪杰之士,

Tomcat的配置与使用

1、Tomcat的简介

讲到Tomcat的使用,我就想起了我刚刚学习JavaWeb时的场景:

老师:这节课我们来讲一下JavaWeb中的服务器昂,它的名字叫Tomcat……..(然后我就发呆去了)

我:没办法呀!下课只能去问大佬喽。

我:大佬大佬,刚刚老师上课讲的服务器Tomcat是什么呀?怎么用呀?

大佬:Tomcat是一个服务器,它可以用来处理客户端的请求,并且将请求处理返回给客户端,巴拉巴拉。

我:

image

最后没办法呀!只能去问度娘了喽。


所以Tomcat就是一个服务器,而且是本地的服务器,可以将我们的Java程序放在Tomcat服务器中,就可以用它来完成不同客户端的请求和响应。当Tomcat启动后,客户端发送请求过来,通过在Tomcat上的Java程序完成请求,然后将处理的结果返回给客户端。

image

官方一点的介绍(百度百科里面的):

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。

Tomcat 服务器是一个免费的开放源代码的Web应用服务器(也是Servlet容器),属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。

2、Tomcat的下载

Tomcat的下载地址:http://tomcat.apache.org/

image

可以发现Tomcat已经升级到Tomcat10的内测版本了,但是我们不需要那么新的,可以选择Tomcat8或者Tomcat9的版本就行。那我这里就选择Tomcat8版本吧,直接点击进去。

image

然后根据自己的电脑下载多少位的文件,相信大家应该都是64位的系统吧。

下载之后解压即可使用了。解压后的目录如下:

image

下面我们来详细的介绍各个文件夹的作用。

  1. bin目录:主要是用来存放tomcat的可执行命令,比如启动和停止。命令主要有两大类:以.bat结尾的是windows命令、以.sh结尾的是linux命令。很多环境变量的设置都在此处,例如可以设置JDK路径、TOMCAT路径,startup 用来启动tomcat,shutdown 用来关闭tomcat,修改catalina可以设置tomcat的内存。
  2. conf目录:主要是用来存放tomcat的一些配置文件。例如端口设置,用户信息配置等。
  3. lib目录:主要用来存放tomcat运行需要加载的jar包。
  4. logs目录:用来存放tomcat在运行过程中产生的日志文件,非常重要的是在控制台输出的日志。(清空不会对tomcat运行带来影响)
  5. temp目录:用来让用户存放tomcat在运行过程中产生的临时文件。(清空不会对tomcat运行带来影响)
  6. webapps目录:用来存放客户端可以访问的资源,比如Java程序,当tomcat启动时会去加载webapps目录下的应用程序。可以以文件夹、war包、jar包的形式发布应用。【核心目录】
  7. work目录:用来存放tomcat在运行时的编译后文件,例如JSP编译后的文件。清空work目录,然后重启tomcat,可以达到清除缓存的作用。

再介绍一下conf目录中一些关键文件:

  1. server.xml文件:该文件用于配置和server相关的信息,比如tomcat启动的端口号、配置host主机、配置Context。【核心文件】
  2. web.xml文件:部署描述文件,这个web.xml中描述了一些默认的servlet,部署每个webapp时,都会调用这个文件,配置该web应用的默认servlet。
  3. tomcat-users.xml文件:配置tomcat的用户密码与权限。
  4. context.xml:定义web应用的默认行为。

到此为止对Tomcat的基本介绍都已经讲完了。那它的使用也是非常简单,所以接下来就来启动Tomcat吧。

注意:在启动tomcat之前,你需要安装好JDK,并且配置好环境变量(这个不会去百度)。然后双击bin目录下的startup.bat(如果一闪而过那就是你存放的路径有问题,多半是因为中文路径导致的)。启动动之后如下图:

image

发现有乱码,此时我们修改tomcat的conf目录下的logging.properties中的参数。

将 java.util.logging.ConsoleHandler.encoding = UTF-8 中的UTF-8改到GBK就行了保存后重启tomcat就正常了。

image

注意别修改其它行的编码。

然后在网页中输入localhost:8080就可以出现页面了。

image

这只是运行了一个空的Tomcat,如果需要Java程序,我只需要将项目打成War包然后拷贝到webapps目录下,然后启动Tomcat即可。

image

启动Tomcat服务,注意这里的访问地址有所改变,需要在后面加一个项目名:http://localhost:8080/HelloTomcat/

image

而我们开发软件经常会用到开发工具如Eclipse、IDEA等,所以接下来介绍一下如何在开发工具上使用Tomcat。

3、在IDEA上使用Tomcat

在Eclipse中的使用就不说了,因为现在Eclipse大家用的越来越少。直接上IDEA吧。

打开IDEA创建一个HelloTomcat项目。

image

Next之后,输入项目名称就创建完成了。那接下配置Tomcat。

点击IDEA中的Add Configuration 或者打开菜单Run --> 选择Edit Configuration 都可以。

弹出窗口后点击+,然后往下滑,然后选择Tomcat Server的Local(如果没有Tomcat Server则点击 items more)。

image

点击Local之后会出现如下界面,然后将我们下载的Tomcat配置进来:

image

注意:不同的IDEA版本界面可能不同,但是大致操作都是一样的。(我的IDEA2018款,我觉得没必要追求最新版本,适合自己的才是最好的)

然后就是在Tomcat中部署并运行项目,当我们配置完Tomcat后,IDEA下面会弹出一个界面。

右击Tomcat选择Artifacts,然后将项目添加进去,在右击Run就可以了。

image

或者在Edit Configurations中,在建立的Tomcat容器中选择Deployment ,点击右边的“+”号然后,选择选择Artifact。

image

然后在下面右击Tomcat运行,就可以在浏览器中查看运行结果了。


IDEA中的Tomcat热部署:

热部署就是应用正在运行的状态下,修改了它的一些源码后,可以在不重启服务器的情况自动把增量内容编译并部署到服务器上,使得修改立即生效。热部署为了解决的问题有两个, 一是在开发的时候,修改代码后不需要重启应用就能看到效果,大大提升开发效率;二是生产上运行的程序,可以在不停止运行的情况下进行升级,不影响用户使用。

要在IDEA中配置Tomcat热部署非常的简单,但前提是有项目在Tomcat中(否则会报404错误)。

在配置Tomcat中Server的配置里,有个on update actionon frame deactivation

  • on update action:表示在当项目启动之后,项目代码更新之后的动作是什么?具体如下:
    • Update resources:只更新资源文件,例如更改了jsp,html等。
    • Update classes and resources:更新类信息和资源文件,但是一般更新类信息都是无效,所以如果更改了类,都会重新部署。
    • Redeploy:重新部署项目(推荐)。
    • Restart server:重新启动服务,尽量不要重新启动服务,因为很慢。

image

  • on frame deactivation:表示当焦点离开IDEA之后会触发哪个更新动作。有三个可以选项:
    • Do nothing:不做任何事。
    • Update resources:只更新资源文件.
    • Update classes and resources:更新类信息和资源文件。

建议设置:

on update action 设置为:Redeploy

on frame deactivation设置为:Update classes and resources

image

配置完后点击Apply即可启动你的tomcat,然后改一下jsp、java文件实验热部署配置是否成功。

注意:IDEA热部署并非绝对实时, 还是会有延时的,假如你手速快的话可能会出现改了并没有马上生效。所以此时不要怀疑热部署没有配置成功,稍微等一会你会看到开发工具左下角会有一个class reload的提示,出现这个提示才说明已经热部。而且如果XML文件有改动的话是不会自动部署的。

4、Tomcat的Server结构

在Tomcat中比较核心的一个文件就是conf目录下的server.xml文件,它主要包含Tomcat一些核心配置文件,如:启动端口,用户配置,Context等,Tomcat的启动首先就是加载这个文件。

我们打开server.xml看上去很复杂。其实大部分都是注释。下面是一个简图说明了各组件之间的关系!

image

Tomcat包含的主要组件:服务器Server,服务Service,连接器Connector、引擎Engine、主机Host、上下文Context等。

Server.xml源文件:

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 -->
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <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>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the
         AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <!--
    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443" />
    -->

    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="localhost">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <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" />

      </Host>
    </Engine>
  </Service>
</Server>

下面简单介绍几个常用组件:

①、Server组件

如上面示例文件中定义的:

<Server port=”8005” shutdown=”SHUTDOWN”>

这会让Tomcat启动一个server实例(即一个JVM),它监听在8005端口以接收shutdown命令。各Server的定义不能使用同一个端口,这意味着如果在同一个物理机上启动了多个Server实例,必须配置它们使用不同的端口。这个端口的定义用于为管理员提供一个关闭此实例的便捷途径,因此,管理员可以直接telnet至此端口使用SHUTDOWN命令关闭此实例。不过,基于安全角度的考虑,这通常不允许远程进行。

Server的相关属性:

  • className: 用于实现此Server容器的完全限定类的名称,默认为org.apache.catalina.core.StandardServer;
  • port: 接收shutdown指令的端口,默认仅允许通过本机访问,默认为8005;
  • shutdown:发往此Server用于实现关闭tomcat实例的命令字符串,默认为SHUTDOWN;

②、Service组件

Service主要用于关联一个引擎和与此引擎相关的连接器,每个连接器通过一个特定的端口和协议接收入站请求交将其转发至关联的引擎进行处理。因此,Service要包含一个引擎、一个或多个连接器。

如上面示例中的定义:

<Service name=”Catalina”>

这定义了一个名为Catalina的Service,此名字也会在产生相关的日志信息时记录在日志文件当中。

Service相关的属性:

  • className: 用于实现service的类名,一般都是org.apache.catalina.core.StandardService。
  • name:此服务的名称,默认为Catalina;

③、Connector组件

进入Tomcat的请求可以根据Tomcat的工作模式分为如下两类:

  • Tomcat作为应用程序服务器:请求来自于前端的web服务器,这可能是Apache, IIS, Nginx等;
  • Tomcat作为独立服务器:请求来自于web浏览器;

Tomcat应该考虑工作情形并为相应情形下的请求分别定义好需要的连接器才能正确接收来自于客户端的请求。一个引擎可以有一个或多个连接器,以适应多种请求方式。

定义连接器可以使用多种属性,有些属性也只适用于某特定的连接器类型。一般说来,常见于server.xml中的连接器类型通常有4种:

  • HTTP连接器
  • SSL连接器
  • AJP 1.3连接器
  • proxy连接器

如上面示例server.xml中定义的HTTP连接器:

<Connector port="8080" protocol="HTTP/1.1" 
  maxThreads="150" connectionTimeout="20000" 
  redirectPort="8443"/>

定义连接器时可以配置的属性非常多,但通常定义HTTP连接器时必须定义的属性只有“port”,定义AJP连接器时必须定义的属性只有"protocol",因为默认的协议为HTTP。以下为常用属性的说明:

  • address:指定连接器监听的地址,默认为所有地址,即0.0.0.0;
  • maxThreads:支持的最大并发连接数,默认为200;
  • port:监听的端口,默认为0;
  • protocol:连接器使用的协议,默认为HTTP/1.1,定义AJP协议时通常为AJP/1.3;
  • redirectPort:如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,则转发至此属性定义的端口;
  • connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为60000,即1分钟;
  • enableLookups:是否通过request.getRemoteHost()进行DNS查询以获取客户端的主机名;默认为true;
  • acceptCount:设置等待队列的最大长度;通常在tomcat所有处理线程均处于繁忙状态时,新发来的请求将被放置于等待队列中;

下面是一个定义了多个属性的SSL连接器:

<Connector port="8443" 
 maxThreads="150" minSpareThreads="25" maxSpareThreads="75" 
 enableLookups="false" acceptCount="100" debug="0" scheme="https" secure="true" 
 clientAuth="false" sslProtocol="TLS" />

④、Engine组件

Engine是Servlet处理器的一个实例,即servlet引擎,默认为定义在server.xml中的Catalina。Engine需要defaultHost属性来为其定义一个接收所有发往非明确定义虚拟主机的请求的host组件。如前面示例中定义的:

<Engine name="Catalina" defaultHost="localhost">

常用的属性定义:

  • defaultHost:Tomcat支持基于FQDN的虚拟主机,这些虚拟主机可以通过在Engine容器中定义多个不同的Host组件来实现;但如果此引擎的连接器收到一个发往非非明确定义虚拟主机的请求时则需要将此请求发往一个默认的虚拟主机进行处理,因此,在Engine中定义的多个虚拟主机的主机名称中至少要有一个跟defaultHost定义的主机名称同名;
  • name:Engine组件的名称,用于日志和错误信息记录时区别不同的引擎;

注:Engine容器中可以包含Realm、Host、Listener和Valve子容器。

⑤、Host组件

位于Engine容器中用于接收请求并进行相应处理的主机或虚拟主机,如前面默认配置文件中定义:

<Host name="localhost" appBase="webapps" 
unpackWARs="true" autoDeploy="true" 
xmlValidation="false" xmlNamespaceAware="false"> 
</Host>

常用属性说明:

  • appBase:此Host的webapps目录,即存放非归档的web应用程序的目录或归档后的WAR文件的目录路径;可以使用基于$CATALINA_HOME的相对路径;
  • autoDeploy:在Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy;默认为true;
  • unpackWars:在启用此webapps时是否对WAR格式的归档文件先进行展开;默认为true;

下面是虚拟主机定义示例:

<Engine name="Catalina" defaultHost="localhost">
 <Host name="localhost" appBase="webapps">
 <Context path="" docBase="ROOT"/>
 <Context path="/bbs" docBase="/web/bss"
  reloadable="true" crossContext="true"/>
 </Host>
 <Host name="mail.test.com" appBase="/web/mail">
 <Context path="" docBase="ROOT"/>
 </Host>
</Engine>

主机别名定义:

如果一个主机有两个或两个以上的主机名,额外的名称均可以以别名的形式进行定义,如下:

<Host name="www.test.com" appBase="webapps" unpackWARs="true">
 <Alias>test.com</Alias>
</Host>

⑥、Context组件

Context组件是最内层次的组件,它表示Web应用程序本身。配置一个Context最主要的是指定Web应用程序的根目录,以便Servlet容器能够将用户请求发往正确的位置。Context组件也可包含自定义的错误页,以实现在用户访问发生错误时提供友好的提示信息。Context在某些意义上类似于apache中的路径别名,一个Context定义用于标识tomcat实例中的一个Web应用程序;如下面的定义:

<!-- Tomcat Root Context -->
<Context path="" docBase="/web/webapps"/>
<!-- buzzin webapp -->
<Context path="/bbs"
 docBase="/web/threads/bbs"
 reloadable="true">
</Context>
<!-- chat server -->
 <Context path="/chat" docBase="/web/chat"/>
<!-- darian web -->
<Context path="/darian" docBase="darian"/>

在Tomcat中,每一个context定义也可以使用一个单独的XML文件进行,其文件的目录为$CATALINA_HOME/conf//。可以用于Context中的XML元素有Loader,Manager,Realm,Resources和WatchedResource。

常用的属性定义有:

  • docBase:相应的Web应用程序的存放位置;也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径;切记,docBase的路径名不能与相应的Host中appBase中定义的路径名有包含关系,比如,如果appBase为deploy,而docBase绝不能为deploy-bbs类的名字;
  • path:相对于Web服务器根路径而言的URI;如果为空“”,则表示为此webapp的根路径;如果context定义在一个单独的xml文件中,此属性不需要定义;
  • reloadable:是否允许重新加载此context相关的Web应用程序的类;默认为false;

⑦、Realm组件

一个Realm表示一个安全上下文,它是一个授权访问某个给定Context的用户列表和某用户所允许切换的角色相关定义的列表。因此,Realm就像是一个用户和组相关的数据库。定义Realm时惟一必须要提供的属性是classname,它是Realm的多个不同实现,用于表示此Realm认证的用户及角色等认证信息的存放位置。

  • JAASRealm:基于Java Authintication and Authorization Service实现用户认证;
  • JDBCRealm:通过JDBC访问某关系型数据库表实现用户认证;
  • JNDIRealm:基于JNDI使用目录服务实现认证信息的获取;
  • MemoryRealm:查找tomcat-user.xml文件实现用户信息的获取;
  • UserDatabaseRealm:基于UserDatabase文件(通常是tomcat-user.xml)实现用户认证,它实现是一个完全可更新和持久有效的MemoryRealm,因此能够跟标准的MemoryRealm兼容;它通过JNDI实现;

下面是一个常见的使用UserDatabase的配置:

<Realm className=”org.apache.catalina.realm.UserDatabaseRealm”
 resourceName=”UserDatabase”/>
下面是一个使用JDBC方式获取用户认证信息的配置:
 <Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"
 driverName="org.gjt.mm.mysql.Driver"
 connectionURL="jdbc:mysql://localhost/authority"
 connectionName="test" connectionPassword="test"
 userTable="users" userNameCol="user_name"
 userCredCol="user_pass"
 userRoleTable="user_roles" roleNameCol="role_name" />

⑧、Valve组件

Valve类似于过滤器,它可以工作于Engine和Host/Context之间、Host和Context之间以及Context和Web应用程序的某资源之间。一个容器内可以建立多个Valve,而且Valve定义的次序也决定了它们生效的次序。Tomcat中实现了多种不同的Valve:

  • AccessLogValve:访问日志Valve
  • ExtendedAccessValve:扩展功能的访问日志Valve
  • JDBCAccessLogValve:通过JDBC将访问日志信息发送到数据库中;
  • RequestDumperValve:请求转储Valve;
  • RemoteAddrValve:基于远程地址的访问控制;
  • RemoteHostValve:基于远程主机名称的访问控制;
  • SemaphoreValve:用于控制Tomcat主机上任何容器上的并发访问数量;
  • JvmRouteBinderValve:在配置多个Tomcat为以Apache通过mod_proxy或mod_jk作为前端的集群架构中,当期望停止某节点时,可以通过此Valve将用记请求定向至备用节点;使用此Valve,必须使用JvmRouteSessionIDBinderListener;
  • ReplicationValve:专用于Tomcat集群架构中,可以在某个请求的session信息发生更改时触发session数据在各节点间进行复制;
  • SingleSignOn:将两个或多个需要对用户进行认证webapp在认证用户时连接在一起,即一次认证即可访问所有连接在一起的webapp;
  • ClusterSingleSingOn:对SingleSignOn的扩展,专用于Tomcat集群当中,需要结合ClusterSingleSignOnListener进行工作;

RemoteHostValve和RemoteAddrValve可以分别用来实现基于主机名称和基于IP地址的访问控制,控制本身可以通过allow或deny来进行定义,这有点类似于Apache的访问控制功能;如下面的Valve则实现了仅允许本机访问/probe:

<Context path="/probe" docBase="probe">
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.0\.0\.1"/>
</Context>

其中相关属性定义有:

  • className:相关的java实现的类名,相应于分别应该为org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve;
  • allow:以逗号分开的允许访问的IP地址列表,支持正则表达式,因此,点号“.”用于IP地址时需要转义;仅定义allow项时,非明确allow的地址均被deny;
  • deny: 以逗号分开的禁止访问的IP地址列表,支持正则表达式;使用方式同allow;

Tomcat Server处理一个HTTP请求的过程:

  1. 用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。
  2. Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。
  3. Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。
  4. Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理)。
  5. path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类。
  6. 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost().执行业务逻辑、数据存储等程序。
  7. Context把执行完之后的HttpServletResponse对象返回给Host。
  8. Host把HttpServletResponse对象返回给Engine。
  9. Engine把HttpServletResponse对象返回Connector。
  10. Connector把HttpServletResponse对象返回给客户Browser。

参考资料:

https://blog.51cto.com/freeloda/1299644

https://blog.csdn.net/u014231646/article/details/79482195

posted @ 2020-04-16 14:19  唐浩荣  阅读(3134)  评论(0编辑  收藏  举报