servlet体系

 抽象机制:

 

 194057_7iOC_3463135.png

 

我们知道 Java Web 应用是基于Servlet 规范运转的,那么 Servlet 本身又是如何运转的呢?为何要设计这样的体系结构

图1:

194057_GQNW_3463135.gif

 

从 上图可以看出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 在容器中的类关联图

194057_PpWp_3463135.gif

上 图可以看出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 相关类结构图

194057_DDDF_3463135.gif

上 图是 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 的转变过程

194057_RSxy_3463135.gif

 

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("/");

 

转载于:https://my.oschina.net/wii01/blog/983752

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值