• 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接口和相关类型的背景信息。
  • 相关阅读:
    文件下载的几种方式
    获取文件的后缀名(转为数组) 字符串和变量的拼接 HTML中字符串和变量的拼接
    小程序之选择拍照或者本地相册
    实时显示时间
    uni-app事件冒泡 如何解决事件冒泡 推荐tap事件
    Codeforces Global Round 7 C. Permutation Partitions(组合数学)
    Codeforces Global Round 7 B. Maximums(逻辑)
    Codeforces Global Round 7 A. Bad Ugly Numbers(数学)
    Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)(单调栈,递推)
    Codeforces Round #622 (Div. 2) B. Different Rules(数学)
  • 原文地址:https://www.cnblogs.com/macula7/p/1960786.html
Copyright © 2020-2023  润新知