了解Tomcat

Tomcat的大名就不用多说了,要学习 java web 肯定会接触到它,可以说是学习 Java web 的前提,所以为了弄明白 Tomcat 的目录结构层次以及它的体系结构,就有了这篇文章,以便让我能更好的理解整个 java web 网站的处理流程,能更快的理解学习吧,当然还有一些配置相关的东西。
在使用Tomcat之前,首先要认识两个环境变量:

  • JAVA_HOME:必须先配置 JAVA_HOME,因为 Tomcat 启动需要使用 JDK
  • CATALANA_HOME:如果是安装版,那么还需要配置这个变量,这个变量用来指定 Tomcat 的安装路径
    如果是绿色版,并且配置了这个环境变量,无论你从那个文件夹执行的启动脚本,最终执行的就是这个环境变量下的 Tomcat,所以最好不要配

目录结构层次

  • bin
    二进制文件以及执行脚本文件(比如启动和关闭)的存放目录。
    常见的几个重要文件:

    catalina.sh :用于启动和关闭 tomcat 服务器
    configtest.sh :用于检查配置文件
    startup.sh :启动 Tomcat 脚本
    shutdown.sh :关闭 Tomcat 脚本

  • conf
    配置文件存放目录。

  • lib
    Tomcat 的库文件夹,用于存放 Tomcat 所依赖的以及第三方扩展的 jar 文件。

  • logs
    日志文件存放目录

    localhost_access_log :访问日志
    localhost.log :错误和其它日志
    manager.log :管理日志
    catalina.log: Tomcat 启动或关闭日志文件

  • temp
    临时文件存放目录
  • webapps
    主要 Web 发布目录(存放我们自己的 JSP, SERVLET,类)
  • work
    存放 Tomcat 编译 JSP 对应的 Java 字节码类文件。

conf目录

server.xml :Tomcat 的全局配置文件
web.xml :为不同的 Tomcat 配置的 web 应用设置缺省值的文件
tomcat-users.xml :Tomcat 用户认证的配置文件


把 Web 应用交给服务器管理的过程称为:虚拟目录映射,比如在 server 配置文件中,我们可以配置一个 web 应用:

1
2
3
<Host>
<Context path="/home" docBase="c:\news" />
</Host>

Context 标签类似于代表一个 web 应用,path 就是对外路径(虚拟路径),如果把 path 设置为空那就成为默认的 web 应用了,说白了虚拟路径就是在输入网址时候的路径,是虚拟的,本地并不存在,后面的 docBase 指定的是本地硬盘的 web 应用的路径,这就是一个映射过程

注:这样搞重启才能生效,所以官方是不建议这样用的,上面只是为演示
通常可以在conf\Catalina\localhost目录下建一个 XML 文件,文件名为虚拟路径(多级目录可以用 # 区分),如果文件名是 ROOT 那就是默认的 web 应用了(并非是默认网页),然后可以在文件内配置 Context,自然 path 就不需要写了,这样会被自动加载,不需要重启


当然最简单的方法是直接往 webapps 目录一扔就 OK 了,文件名就是虚拟目录名


web.xml文件是部署描述符文件,这个文件中注册了很多 MIME 类型,即文档类型。
这些 MIME 类型是客户端与服务器之间说明文档类型的,如用户请求一个 html 网页,那么服务器还会告诉客户端浏览器响应的文档是 text/html 类型的,这就是一个 MIME 类型。
客户端浏览器通过这个 MIME 类型就知道如何处理它了。当然是在浏览器中显示这个 html 文件了。但如果服务器响应的是一个 exe 文件,那么浏览器就不可能显示它,而是应该弹出下载窗口才对。MIME 就是用来说明文档的内容是什么类型的!


tomcat-users 文件,就是存储 tomcat 用户的文件,这里保存的是 tomcat 的用户名及密码,以及用户的角色信息。
可以按着该文件中的注释信息添加 tomcat 用户,然后就可以在 Tomcat 主页中进入 Tomcat Manager 页面了

Webapp目录

这个目录就是用来放 web 应用的,也就是网站的一个个的功能,将开发好的 web 应用(文件夹)仍在这里面就好,然后就是对于一个个的 web 应用也是有一定的目录结构的,如果是静态资源 ( HTML/CSS/JS等 ) 就放在根目录即可,JSP 文件同样也是
如果存在 ROOT 目录那就是默认的应用目录
web 应用程序下还要有一个 WEB-INF 文件夹,注意要大写,里面主要就是放一些 java 相关的东西了:

  • WEB-INF/web.xml 这是一个 Web 应用程序的描述文件。
    这个文件是一个 XML 文件,描述了 Servlet 和这个 Web 应用程序的其他组件信息,此外还包括一些初始化信息和安全约束等等。
    例如,web 应用的默认网页就是在这里配置的
  • WEB-INF/classes/ 这个目录及其下的子目录应该包括这个 Web 应用程序的所有 JavaBean 及 Servlet 等编译好的 Java 类文件(*.class)文件,以及没有被压缩打入 JAR 包的其他 class 文件和相关资源。
    注意:在这个目录下的Java类应该按照其所属的包层次组织目录
  • WEB-INF/lib/ 这个目录是来存放各种 jar 包的
    除了各种依赖 jar,通常 Web-INF/classes/ 这个目录下的类文件也可以打包成 JAR 文件,放在该目录下。如将 classes 目录下的各个*.class文件打包成 WebMis.jar 文件

注意:
WEB-INF 目录中包含应用软件所使用的资源,但是 WEB-INF 却不在公共文档根目录之中。在这个目录中所包含的文件都不能被客户机所访问。
如果一个类出现在 JAR 文件中同时也出现在类的目录中,类加载器会加载位于类目录中的那一个。

如果我们不知道web.xml 应该怎么写,最简单的就是去其他项目或者自带的例子中拷(抄)一份过来,然后改一下就行了,一般就是要它的头和尾

体系结构

一个 Tomcat 只会启动一个 JVM,所有 webapps 公用一个 JVM 进程

Tomcat 体系结构中的六个主要概念:

  • Server
    Server 代表整个容器(container)。它可以包含一个或多个 Service,还可以包含一个 GlobalNamingResources。
    A Server element represents the entire Catalina servlet container. (Singleton)
  • Service
    它由一个或者多个 Connector (连接器)组成,以及一个 Engine (引擎),负责处理所有 Connector 所获得的客户请求。
  • Engine
    • Engine 下可以配置多个虚拟主机 Virtual Host,每个虚拟主机都有一个域名
    • 当 Engine 获得一个请求时,它把该请求匹配到某个Host上,然后把该请求交给该 Host 来处理
    • Engine 有一个默认虚拟主机,当请求无法匹配到任何一个 Host 上的时候,将交给该默认 Host 来处理
  • Host
    • 代表一个 Virtual Host,虚拟主机,每个虚拟主机和某个网络域名 (Domain Name) 相匹配
    • 每个虚拟主机下都可以部署 (deploy)一个或者多个 Web App,每个 Web App 对应于一个 Context,有一个 Context path
    • 当 Host 获得一个请求时,将把该请求匹配到某个 Context 上,然后把该请求交给该 Context 来处理
    • 匹配的方法是“最长匹配”,所以一个 path=="" 的 Context 将成为该 Host 的默认 Context
    • 所有无法和其它 Context 的路径名匹配的请求都将最终和该默认 Context 匹配
  • Connector
    Tomcat 有两个典型的 Connector,一个直接侦听来自浏览器的 http 请求,一个侦听来自其它 WebServer 的请求
    当然现在 https 也越来越普遍了
  • Context
    • 一个 Context 对应于一个 Web Application,一个 Web Application 由一个或者多个 Servlet 组成
    • Context 在创建的时候将根据配置文件 $CATALINA_HOME$/conf/web.xml$WEBAPP_HOME$/WEB-INF/web.xml 载入 Servlet 类
    • 当 Context 获得请求时,将在自己的映射表 (mapping table) 中寻找相匹配的 Servlet 类
    • 如果找到,则执行该类,获得请求的回应,并返回

CATALINA_HOME 是 Tomcat 的安装目录,CATALINA_BASE 是 Tomcat 的工作目录。
当我们想要运行多个 Tomcat 实例,但是不想拷贝多个 Tomcat 副本时,那么我们可以配置多个不同工作目录 (修改 catalina.sh 文件)

如何处理一个请求

假设来自客户的请求为:http://localhost:8080/test/index.jsp 对照上面的图更好理解

  1. 请求被发送到本机端口 8080,被在那里侦听 http 的连接器 ( Coyote HTTP/1.1 Connector ) 获得
  2. Connector 把该请求交给它所在的 Service 的 Engine 来处理,并等待来自 Engine 的回应
  3. Engine 获得请求 localhost/test/index.jsp,匹配它所拥有的所有虚拟主机 ( Virtual Host )
  4. Engine 匹配到名为 localhost 的 Host(即使匹配不到也把请求交给该 Host 处理,因为该 Host 被定义为该 Engine 的默认主机)
  5. localhost Host 获得请求/test/index.jsp,匹配它所拥有的所有 Context
  6. Host 匹配到路径为 /test 的 Context(如果匹配不到就把该请求交给路径名为""的默认 Context 去处理)
  7. path="/test" 的 Context 获得请求 /index.jsp,在它的 mapping table 中寻找对应的 servlet
  8. Context 匹配到 URL PATTERN 为 *.jsp 的 servlet,对应于 JspServlet 类
  9. 构造 HttpServletRequest 对象和 HttpServletResponse 对象,作为参数调用 JspServlet 的 doGet 或 doPost 方法
  10. Context 把执行完了之后的 HttpServletResponse 对象返回给 Host
  11. Host 把 HttpServletResponse 对象返回给 Engine
  12. Engine 把 HttpServletResponse 对象返回给 Connector
  13. Connector把 HttpServletResponse 对象返回给客户浏览器

配置相关

用到了就来补充,现在应该很乱,等数量够了再集中整理一下

context相关

前面提到过:Context 标签类似于代表一个 web 应用
path 属性就是对外路径(虚拟路径),如果设为path="" 就代表默认应用
docBase 属性为映射的物理路径
reloadable:是否自动加载,如果设置为 true 就是自动加载,开发调试时小的应用可以开,大的应用就不要开了,可能会内存溢出

配置用户

用户相关的配置在 tomcat-users 文件下,默认也有几个,但是被注释了,如果想进入管理页面还需要手动加一个管理员的权限

1
2
3
4
5
6
<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="manager"/>
<user username="tomcat" password="tomcat" roles="tomcat,manager"/>
<user username="both" password="tomcat" roles="tomcat,role1"/>
<user username="role1" password="tomcat" roles="role1"/>

然后就可以在 Tomcat 主页中进入Tomcat Manager 页面了,就是 http://localhost:8080/manager/html

单向加密连接器

当然在实际的环境下,都是双向加密,这里只是稍微提一下,以后再补充
我们可以用java自带的 keytool 工具生成一个密钥库:
keytool -genkey -alias mytest -keyalg RSA
上面的命令在生成密钥库的时候指定了一个别名叫 mytest,以及指定了算法是 RSA,当然还可以指定有效期,还有很多参数如加 -keystore 后面跟指定保存的路径,其他的就不多说了,只说下常用的,然后输入域名和密码即可,其他的可忽略
弄好以后会生成一个 .keystore 文件,然后可以把它放到 Tomcat 的目录里去,比如放到 conf 下,并且配置它的全局配置文件 server.xml 打开 HTTPS 的连接器,设置密钥库的路径( keystoreFile )和密码( keystorePass )属性。
当然,要想让浏览器信任,需要 CA 的签名的证书
上面只是给服务器生成了证书,要做到双向加密还需要给客户端(浏览器)也生成证书,并且要让服务器信任客户端的证书,客户端也需要信任服务器的证书,这个过程比较复杂,但是也不难,可以自行Google资料

补充

当我们的web应用开发好以后要部署在服务器上,通常当然要先打一个包,然后再上传到服务器,这样既能保证数据的完整,还能节省点流量,java有打包工具,包就是我们常说的jar包,但是一般会命名为 .war 后缀,因为这种后缀Tomcat会自动进行解压

参考

http://qiita.com/CoffeeDog/items/7082c1db5ab84c8df60b
http://blog.csdn.net/clementad/article/details/46842309

喜欢就请我吃包辣条吧!

评论框加载失败,无法访问 Disqus

你可能需要魔法上网~~