zoukankan      html  css  js  c++  java
  • Tomcat源码学习(12)How Tomcat works(转)

    应用程序2

    第一个应用程序有一个严重的问题。在ServletProcessor1类的process方法,你向上转换ex02.pyrmont.Request实例为javax.servlet.ServletRequest,并作为第一个参数传递给servlet的service方法。你也向下转换ex02.pyrmont.Response实例为javax.servlet.ServletResponse,并作为第二个参数传递给servlet的service方法。
    try {
    servlet = (Servlet) myClass.newInstance();
    servlet.service((ServletRequest) request,(ServletResponse) response);
    }
        这会危害安全性。知道这个servlet容器的内部运作的Servlet程序员可以分别把ServletRequest和ServletResponse实例向下转换为ex02.pyrmont.Request和ex02.pyrmont.Response,并调用他们的公共方法。拥有一个Request实例,它们就可以调用parse方法。拥有一个Response实例,就可以调用sendStaticResource方法。
    你不可以把parse和sendStaticResource方法设置为私有的,因为它们将会被其他的类调用。不过,这两个方法是在个servlet内部是不可见的。其中一个解决办法就是让Request和Response类拥有默认访问修饰,所以它们不能在ex02.pyrmont包的外部使用。不过,这里有一个更优雅的解决办法:通过使用facade类。请看Figure 2.2中的UML图。
    Figure 2.2: Façade classes
    在这第二个应用程序中,我们增加了两个façade类: RequestFacade和ResponseFacade。RequestFacade实现了ServletRequest接口并通过在构造方法中传递一个引用了ServletRequest对象的Request实例作为参数来实例化。ServletRequest接口中每个方法的实现都调用了Request对象的相应方法。然而ServletRequest对象本身是私有的,并不能在类的外部访问。我们构造了一个RequestFacade对象并把它传递给service方法,而不是向下转换Request对象为ServletRequest对象并传递给service方法。Servlet程序员仍然可以向下转换ServletRequest实例为RequestFacade,不过它们只可以访问ServletRequest接口里边的公共方法。现在parseUri方法就是安全的了。
    Listing 2.7 显示了一个不完整的RequestFacade类
    Listing 2.7: RequestFacade类
    package ex02.pyrmont;
    public class RequestFacade implements ServletRequest {
    private ServleLRequest request = null;
    public RequestFacade(Request request) {
    this.request = request;
    }
    /* implementation of the ServletRequest*/
    public Object getAttribute(String attribute) {
    return request.getAttribute(attribute);
    }
    public Enumeration getAttributeNames() {
    return request.getAttributeNames();
    }
    ...
    }
        请注意RequestFacade的构造方法。它接受一个Request对象并马上赋值给私有的servletRequest对象。还请注意,RequestFacade类的每个方法调用ServletRequest对象的相应的方法。
    这同样使用于ResponseFacade类。
    这里是应用程序2中使用的类:
    • HttpServer2
    • Request
    • Response
    • StaticResourceProcessor
    • ServletProcessor2
    • Constants
    HttpServer2类类似于HttpServer1,除了它在await方法中使用ServletProcessor2而不是ServletProcessor1:
    if (request.getUri().startWith("/servlet/")) {
         servletProcessor2 processor = new ServletProcessor2();
    processor.process(request, response);
    }
    else {
    ...
    }
        ServletProcessor2类类似于ServletProcessor1,除了process方法中的以下部分:
    Servlet servlet = null;
    RequestFacade requestFacade = new RequestFacade(request);
    ResponseFacade responseFacade = new ResponseFacade(response);
    try {
    servlet = (Servlet) myClass.newInstance();
    servlet.service((ServletRequest) requestFacade,(ServletResponse)responseFacade);
    }

    运行应用程序

    要在Windows上运行该应用程序,在工作目录下面敲入以下命令:
    java -classpath ./lib/servlet.jar;./ ex02.pyrmont.HttpServer2
        在Linux下,你使用一个冒号来分隔两个库:
    java -classpath ./lib/servlet.jar:./ ex02.pyrmont.HttpServer2
        你可以使用与应用程序1一样的地址,并得到相同的结果。

    总结

    本章讨论了两个简单的可以用来提供静态资源和处理像PrimitiveServlet这么简单的servlet的servlet容器。同样也提供了关于javax.servlet.Servlet接口和相关类型的背景信息。
  • 相关阅读:
    C#基础—string等类的有趣方法_1
    设计模式
    OOP-面向对象程序设计
    CSS3实用效果大全
    HTML5 DOM元素类名相关操作API classList简介(转载自张鑫旭大神)
    Js写的一个倒计时效果实例
    垂直居中的几种方案
    大图片加载优化解决方案
    DomReady实现策略
    脱离文档流
  • 原文地址:https://www.cnblogs.com/macula7/p/1960786.html
Copyright © 2011-2022 走看看