在学习Servlet/JSP时,有个重要的概念:“Web容器是Servlet/JSP唯一认得的HTTP服务器。”如果希望用Servlet/JSP编写的Web应用程序可以正常运作,就必须知道Servlet/JSP如何与Web容器沟通,Web容器如何管理Servlet/JSP的各种对象等问题。
当开始编写Servlet/JSP程序时,必须开始接触容器的概念,容器这个名词也用在如List、Set这类Collection上,也就是用来持有、保存对象的集合对象。对于编写Servlet/JSP来说,容器不仅持有对象,还负责对象的生命周期与相关服务的连接。
在具体层面,容器其实就是一个用Java写的程序,运行在JVM之上,不同类型的容器会负责不同的工作,若以Servlet/JSP运行的Web容器来说,也是一个Java写的程序。将来编写Servlet时,会接触HttpServletRequest、HttpServletResponse等对象,HTTP那些文字性的通信协议,如何变成Servlet/JSP中可用的Java对象的?其实就是容器为你剖析与转换的。
在抽象层面,可以将Web容器视为运行Servlet/JSP的HTTP服务器。就如同Java程序仅认得JVM这个操作系统,Servlet/JSP程序在抽象层面上,也仅认得Web容器这个概念上的HTTP服务器,只要写的Servlet/JSP符合Web容器的标准规范,Servlet/JSP就可以在各种不同的厂商实现的Web容器上运行,而不用理会底层真正的HTTP服务器是什么。
就如同JVM介于Java程序与实体操作系统之间,Web容器是介于HTTP服务器与Servlet之间,也正如编写Java程序必须了解JVM与应用程序之间如何互动,编写Servlet/JSP也必须知道Web容器如何与Servlet/JSP互动,如何管理Servlet等事实(JSP最后也是转译、编译、加载为Servlet,在容器的世界中,真正负责请求、响应的是Servlet)。
下面是一个请求/响应的基本例子:
1) 客户端(大部分情况下是浏览器)对Web服务器发出HTTP请求。
2) HTTP服务器收到HTTP请求,将请求转由Web容器处理,Web容器会剖析HTTP请求内容,创建各种对象(如HttpServletRequest、HttpServletResponse、HttpSession等)。
3) Web容器由请求的URL决定要使用哪个Servlet来处理请求(事先由开发人员定义)。
4) Servlet根据请求对象(HttpServletRequest)的信息决定如何处理,通过响应对象(HttpServletResponse)来创建响应。
5) Web容器与HTTP服务器沟通,Web服务器将响应转换为HTTP响应并传回客户端。
Servlet是执行在Web容器之中,Web容器是由服务器上的JVM启动,JVM本身就是服务器上的一个可执行程序,当一个请求来到时,Web容器会为每个请求分配一个线程。如果有多个请求进来,就只是启动多个线程来进行处理,而不是重复启动多次JVM。
需要注意的是,Web容器可能会使用同一个Servlet实例来服务多个请求。也就是说,多个请求下,就相当于多个线程在共享存取一个对象,因此得注意线程安全的问题。