现在的位置: 首页 > 综合 > 正文

How Tomcat Works 2

2018年05月22日 ⁄ 综合 ⁄ 共 3489字 ⁄ 字号 评论关闭

 这一章主要有两个需要注意的地方,一个是javax.servlet.Servlet接口,另一个是Facade模式,Application里加入了对servlet的支持。

 

一 Servlet接口

有关servlet的类和接口都包含在javax.servlet包和javax.servlet.http包中,其中最重要的是javax.servlet.Servlet接口,因为所有的servlet都直接或间接的实现了它。

这个接口有5个方法:

public void init(ServletConfig config) throws ServletException

public void service(ServletRequest request, ServletResponse response) throws ServletException, java.io.IOException

public void destroy()

public ServletConfig getServletConfig()

public java.lang.String getServletInfo()

 

1,先说最简单的getServletInfo方法,返回此servlet的信息,比如作者版本等。一般是返回空字符串,如果需要可以重写。

 

2,getServletConfig方法,返回类型是javax.servlet.ServletConfig,就是init方法中传入的那个实例。

ServletConfig类里有四个方法:

第一个方法得到servlet的名字。第三第四个方法是从web.xml里设置servlet时得到的初始参数。

第二个方法得到一个javax.servlet.ServletContext。这个类是servlet和container交互用的,比如得到context path等。

 

关于ServletConfig接口,将在11章中详细描述。

3,剩下的三个方法与servlet的生命周期相关。首先是init,此方法在servlet初始化后调用,并只调用一次!servlet容器调用此方法来指示这个servlet可以接收客户端请求了。如果出现了下面两种情况之一,则表示此servlet不可用:

a,抛出ServletException

b,在一段时间内不能返回



4,

service方法会紧接着init被调用,用来响应用户请求。两个参数 javax.servlet.ServletRequest和javax.servlet.ServletResponse将在后面说明。如果servlet抛出异常或出现错误,那么应该在response中设置

status code。需要特别注意的是以下说明:

     * Servlets typically run inside multithreaded servlet containers
     * that can handle multiple requests concurrently. Developers must
     * be aware to synchronize access to any shared resources such as files,
     * network connections, and as well as the servlet's class and instance
     * variables.
     * More information on multithreaded programming in Java is available in
     * <a href="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">
     * the Java tutorial on multi-threaded programming</a>.

因为一般情况下servlet只有一个实例
并且
处于多线程调用状态,所以要特别注意对共享资源的同步。(关于servlet在容器中仅有一个实例,在《用户每次访问servlet时,是否返回的是同一个实例?》中详细描述了)


5,destyoy方法。

destroy方法在容器移除servlet
时执行,同样只执行一次。这个方法会在所有的线程的service()方法执行完成或者超时后执行,调用这个方法后,容器不会再调用这个servlet的
方法,也就是说容器不再把请求发送给这个servlet。这个方法给servlet释放占用的资源的机会,通常用来执行一些清理任务,并且保存任何这个实例在内存中需要保存的永久性信息

关于何时调用此方法,书中:This normally happens when the servlet container is shut down or the servlet container needs some free memory.

 

二 Facade模式

Facade模式可以应用于:

  ● 不需要使用一个复杂系统的所有功能,而且可以创建一个新的类,包含访问系统的所有规则。如果只需要使用系统的部分功能(这是通常的情况),那么你为新类所创建的API将比原系统的API简单得多。

  ● 希望封装或者隐藏原系统。

  ● 希望使用原系统的功能,而且还希望增加一些新的功能。

  ● 编写新类的成本小于所有人学会使用或者未来维护原系统上所需的成本。

在这一章中,增加了对servlet请求的处理,如果用户请求一个servlet本章中的例子程序将略过init和destyoy等,只简单的调用servlet的service方法。注意service方法有两个参数:ServletRequest request, ServletResponse response,在此仅以ServletRequest为例,ServletResponse类似。

ServletRequest接口主要描述了客户端request的请求,包括parameter name and values, attributes, and an input stream等。在此章的应用程序中,只写了一个Request类简单继承了这个接口,保留继承下来的方法为空,并且添加了parse和getUri等方法。注意parse和getUri方法是不希望暴露给servlet设计者,但是,如果容器设计成只是简单的生成Request类实例,并且向上转型传入到service方法的话,在service方法内,servlet设计者如果知道传入的参数是Request类的话,可以通过向下转型成Request类,这样就可以在servlet内部访问parse和getUri方法了。这是违反安全的。

为了解决这个问题,使用了Facade模式封装了Request类。步骤是先建立一个RequestFacade类,继承ServletRequest接口,类中包含一个ServletRequest类型的私有变量,提供一个可以注入这个私有变量的构造方法,并且只提供那些希望暴露给servlet设计者的方法,也就是ServletRequest接口中的方法,在方法体中返回私有变量的对应方法。这样,在service方法中,即使再向下转型成RequestFacade方法,也不可能访问到parse和getUri这样的方法了。如:

 

public class RequestFacade implements ServletRequest {

  private ServletRequest request = null;

  public RequestFacade(Request request) {
    this.request = request;
  }

  /* implementation of the ServletRequest*/

 public Object getAttribute(String attribute) {
    return request.getAttribute(attribute);
  }

。。。。。。

}

 

三 Application

第一个应用程序添加了对servlet请求的支持,但只是简单调用service方法。

第二个应用程序使用了Facade模式封装了Request和Response,提高了安全性。

【上篇】
【下篇】

抱歉!评论已关闭.