我们开发的web应用都是跑在web容器中的。Tomcat就是一个常用的Web容器。对于java web开发,安装好jdk及java集成开发工具后,第一要紧的事是安装tomcat。在linux下,从tomcat官网下载tomcat压缩文件后,直接解压就可以了。进入tomcat目录,能看到如下目录:
其中bin目录是里存放了tomcat的启动脚本,conf目录保存的是tomcat的配置文件。在命令行中进入bin目录,执行
$sh ./catalina.sh run
就可以启动tomcat了。在浏览器输入localhost:8080,如果看到以下内容,就说明tomcat启动成功了:
我们开发的web应用,可以认为就是一个”网站“。只有将web应用放到tomcat容器里运行,我们才可以访问到。那么,我们编写的web应用要放到tomcat的什么地方才能运行呢?要符合什么规范才能运行呢?tomcat怎么运行放置在其中的web应用呢?
Tomcat规定,所有的web应用,都放在它的webapps目录下,每个web应用对应该目录下的一个子目录。进入tomcat的webapps目录,可以看到如下:
除了springtest这个子目录是我创建的之外,其他的几个子目录都是tomcat自带的。从上图可以看出,tomcat自带了examples、manage等多个web应用,springtest这个Web应用是我部署上去的。
Tomcat规定了每个web应用的格式,以springtest这个web应用为例,先看看其目录:
在springtest目录下,有WEB-INF子目录,在WEB-INF目录下,有配置文件web.xml,另外有classes目录,一般是用来存放编译好的java字节码文件;而lib目录通用用来存放web应该所依赖的jar包。
tomcat规定,每个web应用必须具有WEB-INF子目录,在WEB-INF目录下必须存放有web.xml配置文件。Tomcat启动后,对于webapps下的每个应用(目录),都会先去它的WEB-INF目录下读取配置文件web.xml,然后通过加载该应用下的相关类文件,进而完成该web应用的启动工作。
Web应用启动后,tomcat又是怎么处理http请求的呢?一个tomcat容器下可以有多个web应用,tomcat是怎么知道哪个http请求给哪个web应用处理呢?tomcat是根据http请求的uri来决定将请求交给哪个web应用来处理的。以上面为例,所有访问http://localhost:8080/springtest/xxxx的请求都会交给springtest这个应用处理,而所有访问http://localhost:8080/manager/xxxx的请求都会交给manager应用处理。而如果请求没有写请求路径,比如访问http://localhost:8080的请求则会交给ROOT这个应用处理,因为ROOT应用是tomcat的默认应用。
Tomcat决定了将请求交给哪个web应用处理后,web应用又是怎么处理这个请求的呢?tomcat是符合servlet规范的web容器,servlet规范规定,http请求是由servlet来处理的,因此,每个web应用都应该编写自己的servlet,tomcat根据http请求的uri决定将请求交给哪个servlet处理,servlet处理后生成相应的response返回给tomcat,再由tomcat将response返回给客户端。而每个web应用的WEB-INF目录下的web.xml配置文件,就是用来告诉tomcat该web应用有哪些servlet,它的类是什么,它们各处理什么类型的uri的http请求。以springtest为例,其web.xml配置文件如下所示:
<?xmlversion="1.0" encoding="UTF-8"?>
<web-app version="3.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!--配置DispatcherServlet-->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
其中<servlet-name>定义了servlet的名称,<servlet-class>则指明了servlet类的全限定名,<servlet-mapping>元素则定义了该servlet处理哪些uri格式的请求,“/”表示处理所有的请求。从上面的web.xml配置文件可以看出,springtest只定义了一个servlet,且该servlet处理所有的http请求。