抽象机制:
我们知道 Java Web 应用是基于Servlet 规范运转的,那么 Servlet 本身又是如何运转的呢?为何要设计这样的体系结构
图1:
从 上图可以看出Servlet 规范就是基于这几个类运转的,与 Servlet 主动关联的是三个类,分别是 ServletConfig、ServletRequest 和 ServletResponse。这三个类都是通过容器传递给 Servlet 的,其中 ServletConfig 是在 Servlet 初始化时就传给 Servlet 了,而后两个是在请求达到时调用 Servlet 时传递过来的。我们很清楚 ServletRequest 和 ServletResponse 在 Servlet 运行的意义,但是 ServletConfig 和 ServletContext 对 Servlet 有何价值?仔细查看 ServletConfig 接口中声明的方法发现,这些方法都是为了获取这个Servlet 的一些配置属性,而这些配置属性可能在 Servlet 运行时被用到。而 ServletContext 又是干什么的呢? Servlet 的运行模式是一个典型的“握手型的交互式”运行模式。所谓“握手型的交互式”就是两个模块为了交换数据通常都会准备一个交易场景,这个场景一直跟随个这个 交易过程直到这个交易完成为止。这个交易场景的初始化是根据这次交易对象指定的参数来定制的,这些指定参数通常就会是一个配置类。所以对号入座,交易场景 就由 ServletContext 来描述,而定制的参数集合就由ServletConfig 来描述。而 ServletRequest 和 ServletResponse 就是要交互的具体对象了,它们通常都是作为运输工具来传递交互结果。
ServletConfig 是在 Servlet init 时由容器传过来的,那么ServletConfig 到底是个什么对象呢?
下图是ServletConfig 和 ServletContext 在 Tomcat 容器中的类关系图。
图 6. ServletConfig 在容器中的类关联图
上 图可以看出StandardWrapper 和 StandardWrapperFacade 都实现了 ServletConfig 接口,而 StandardWrapperFacade 是 StandardWrapper 门面类。所以传给 Servlet 的是 StandardWrapperFacade 对象,这个类能够保证从StandardWrapper 中拿到 ServletConfig 所规定的数据,而又不把 ServletConfig 不关心的数据暴露给 Servlet。
同样ServletContext 也与 ServletConfig 有类似的结构,Servlet 中能拿到的 ServletContext 的实际对象也是 ApplicationContextFacade 对象。ApplicationContextFacade 同样保证 ServletContex 只能从容器中拿到它该拿的数据,它们都起到对数据的封装作用,它们使用的都是门面设计模式。
通过ServletContext 可以拿到 Context 容器中一些必要信息,比如应用的工作路径,容器支持的 Servlet 最小版本等。
>>servletContext:
一个servlet上下文是servlet引擎提供用来服务于Web应用的接口,在web项目之前被创建,由交易的对象指定的参数进行初始化(他与tomcat的整个容器有关)。
内涵:
1.一个web应用只有一个servletContext,并且生命周期伴随着整个web应用,所以servletContext的数据是共享的,能在多个servlet中使用。
2.servletContext能获取web应用的配置信息等,ServletContext 是一个接口
都是由容器来实例化产生对象,传递给servletConfig
例:ServletConfig:
public ServletContext getServletContext();
3. ServletContext 是负责和 Servlet 的上文和下文交互,上面和 Servlet 容器交互,下面和Servlet 中的请求和相应进行交互
例:
ServletContext application=sce.getServletContext();//公共的对象
联系:服务器的四大域对象:装数据的空间
PageContext:只在一个页面内有效
Request:一次请求范围内有效 相对ie而言
Session: 与浏览器有关,浏览器关闭session销毁。
Application:应用对象,在应用启动的时候产生,应用关闭的时候注销
>>servletConfig:
servletConfig是给servlet指定配置一些属性的类,在容器对servlet初始化的时候会将对servlet所配置的参数(web.xml),记录到servletConfig中。
代码参考(servlet api.html)
内涵:
1. servletConfig由容器来实例化,本身是个接口,是由容器产生一格 ServletConfig 的实现类的对象,然后传递给 Servlet
例:
public void init(ServletConfig config) throws ServletException {
System.out.println("初始化 ....init");
//取参数
pwd=config.getInitParameter("pwd");
}
Servlet 中定义的两个 ServletRequest 和 ServletResponse 它们实际的对象又是什么呢?,我们在创建自己的 Servlet 类时通常使用的都是 HttpServletRequest 和 HttpServletResponse,它们继承了 ServletRequest 和 ServletResponse。为何 Context 容器传过来的 ServletRequest、ServletResponse 可以被转化为 HttpServletRequest 和 HttpServletResponse 呢?
图 7.Request 相关类结构图
上 图是 Tomcat 创建的 Request 和 Response 的类结构图。Tomcat 一接受到请求首先将会创建org.apache.coyote.Request 和 org.apache.coyote.Response,这两个类是 Tomcat 内部使用的描述一次请求和相应的信息类它们是一个轻量级的类,它们作用就是在服务器接收到请求后,经过简单解析将这个请求快速的分配给后续线程去处理,所 以它们的对象很小,很容易被 JVM 回收。接下去当交给一个用户线程去处理这个请求时又创建 org.apache.catalina.connector. Request 和org.apache.catalina.connector. Response 对象。这两个对象一直穿越整个Servlet 容器直到要传给 Servlet,传给Servlet 的是 Request 和 Response 的门面类 RequestFacade 和 RequestFacade,这里使用门面模式与前面一样都是基于同样的目的——封装容器中的数据。一次请求对应的 Request 和 Response 的类转化如下图所示:
图 8.Request 和Response 的转变过程
1.ServletContext与ServletConfig:
ServletContext是Servlet容器上下文环境对象,定义一组方法,servlet 使用这些方法与其 servlet 容器进行通信,例如,获取文件的 MIME 类型、分发请求或写入日志文件
每个web应用都有且仅有一个ServletContext对象,这个对象在所有的Servlet都可以使用。
ServletContext 对象包含在ServletConfig 对象中,ServletConfig 对象在初始化Servlet 时由Web 服务器提供给Servlet。
ServletContext在jsp中用application内置对象来表示,而在Servlet中通过调用方法
ServletContext sc = getServletContext();
来获取。
因为一个web应用就一个ServletContext 对象,因此可以使用ServletContext 来做一些全局性的属性设置等。比如网站访问计数器等等。下面给出一个简单的页面计数器:
<body>
<%
Integer x = (Integer) application.getAttribute(
"num"
);
if (x == null
) {
application.setAttribute(
"num"
, 1);
}
else
{
application.setAttribute(
"num"
, ++x);
}
out.println(
"您是第"+x+"位访客!"
);
%>
</body>
获取资源绝对路径:
getServletContext().getRealPath("/");