Servlet工作原理
Extract From:
http://www.ibm.com/developerworks/cn/java/j-lo-servlet/index.html
Tomcat 的容器分为四个等级,
真正管理 Servlet 的容器是 Context 容器,
一个 Context 对应一个 Web 工程
给Tomcat增加一个web工程:
1 Tomcat tomcat = getTomcatInstance();
2 File appDir = new File(getBuildDirectory(), "webapps/examples");
3 tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
4 tomcat.start();
5 ByteChunk res = getUrl("http://localhost:" + getPort() +
6 "/examples/servlets/servlet/HelloWorldExample");
7 assertTrue(res.toString().indexOf("<h1>Hello World!</h1>") > 0);
Tomcat 的启动逻辑是基于观察者模式设计的,所有的容器都会继承 Lifecycle 接口。
它管理着容器的整个生命周期,所有容器的的修改和状态的改变都会由它去通知已经注册的观察者(Listener)。
ContextConfig 类会负责整个 Web 应用的配置文件的解析工作。
StandardWrapper 是 Tomcat 容器中的一部分,它具有容器的特征, 而 Servlet 为了一个独立的 web 开发标准,不应该强耦合在 Tomcat 中。
因此,Tomcat 将 Servlet 包装成 Context 容器中的 StandardWrapper。
Context 容器才是真正运行 Servlet 的 Servlet 容器。
一个 Web 应用对应一个 Context 容器,容器的配置属性由应用的 web.xml 指定
在解析配置文件时会读取默认的 globalWebXml,在 conf 下的 web.xml 文件中定义了一些默认的配置项, 其定义了两个 Servlet,分别是: org.apache.catalina.servlets.DefaultServlet 和 org.apache.jasper.servlet.JspServlet
Java Web 应用是基于 Servlet 规范运转的
Servlet 的运行模式是一个典型的“握手型的交互式”运行模式。
所谓“握手型的交互式”就是两个模块为了交换数据通常都会准备一个交易场景,这个场景一直跟随个这个交易过程直到这个交易完成为止。
这个交易场景的初始化是根据这次交易对象指定的参数来定制的,这些指定参数通常就会是一个配置类。
所以对号入座, 交易场景就由 ServletContext 来描述, 而定制的参数集合就由 ServletConfig 来描述。
而 ServletRequest 和 ServletResponse 就是要交互的具体对象了,它们通常都是作为运输工具来传递交互结果。
Servlet 的确已经能够帮我们完成所有的工作了,但是现在的 web 应用很少有直接将交互全部页面都用 servlet 来实现, 而是采用更加高效的 MVC 框架来实现。
这些 MVC 框架的基本原理都是将所有的请求都映射到一个 Servlet,然后去实现 service 方法,这个方法也就是 MVC 框架的入口。
Servlet 能够给我们提供两部分数据,
一个是在 Servlet 初始化时调用 init 方法时设置的 ServletConfig,这个类基本上含有了 Servlet 本身和 Servlet 所运行的 Servlet 容器中的基本信息。
根据前面的介绍 ServletConfig 的实际对象是 StandardWrapperFacade,到底能获得哪些容器信息可以看看这个类提供了哪些接口。
还有一部分数据是由 ServletRequest 类提供,它的实际对象是 RequestFacade,从提供的方法中发现主要是描述这次请求的 HTTP 协议的信息。