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 | <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
对照上面的图更好理解
- 请求被发送到本机端口 8080,被在那里侦听 http 的连接器 ( Coyote HTTP/1.1 Connector ) 获得
- Connector 把该请求交给它所在的 Service 的 Engine 来处理,并等待来自 Engine 的回应
- Engine 获得请求
localhost/test/index.jsp
,匹配它所拥有的所有虚拟主机 ( Virtual Host ) - Engine 匹配到名为 localhost 的 Host(即使匹配不到也把请求交给该 Host 处理,因为该 Host 被定义为该 Engine 的默认主机)
- localhost Host 获得请求
/test/index.jsp
,匹配它所拥有的所有 Context - Host 匹配到路径为 /test 的 Context(如果匹配不到就把该请求交给路径名为
""
的默认 Context 去处理) path="/test"
的 Context 获得请求 /index.jsp,在它的 mapping table 中寻找对应的 servlet- Context 匹配到 URL PATTERN 为
*.jsp
的 servlet,对应于 JspServlet 类 - 构造 HttpServletRequest 对象和 HttpServletResponse 对象,作为参数调用 JspServlet 的 doGet 或 doPost 方法
- Context 把执行完了之后的 HttpServletResponse 对象返回给 Host
- Host 把 HttpServletResponse 对象返回给 Engine
- Engine 把 HttpServletResponse 对象返回给 Connector
- Connector把 HttpServletResponse 对象返回给客户浏览器
配置相关
用到了就来补充,现在应该很乱,等数量够了再集中整理一下
context相关
前面提到过:Context 标签类似于代表一个 web 应用
path 属性就是对外路径(虚拟路径),如果设为path=""
就代表默认应用
docBase 属性为映射的物理路径
reloadable:是否自动加载,如果设置为 true 就是自动加载,开发调试时小的应用可以开,大的应用就不要开了,可能会内存溢出
配置用户
用户相关的配置在 tomcat-users
文件下,默认也有几个,但是被注释了,如果想进入管理页面还需要手动加一个管理员的权限
1 | <role rolename="tomcat"/> |
然后就可以在 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
你可能需要魔法上网~~