coder 爱翻译 How Tomcat Works 第二章 第二部分

Application 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容器的内部工作原理可以向下把SevletRequest和ServletResponse实例转型为ex02.pyrmont.Request和ex02.pyrmont.Response,然后调用它们的public方法。有一个Request实例,它以调用它的parse方法。有一个Response实例,可以调用它的sendStaticResource方法。

你不能把parse和sendStaticResource方法设置成为private,因为它们会被其他类调用。但是,这两个方法不打算对这个servlet以外的其他类使用。一个解决办法是:把Request和Response类设置为默认访问修饰符(default access modifier),这样它们不能被ex02.pytmont包外的其他类使用。不过,这里有一个更加优雅的解决办法:使用facade类。

在这个应用,我们增加两个类:RequestFacade和ResponseFacade。RequestFacade实现了ServletRequest接口。在它通过传递一个Request实例交给一个ServletRequest对象的引用来实例化。这个ServletRequest接口的每个方法实现调用这个Request对象的相应的方法。这样,ServletRequest对象它自己是private,不能被外面的类访问。以前是通过向上转型Request对象为ServletRequest,然后传递给service方法。现在我们构建了一个RequestFacade对象然后把它传给service方法替代前一种方法。Servlet程序员任然可以向下转型ServletRequest实例为RequestFacade,但是他们只能访问在ServletRequest接口中允许访问的方法。现在parseUri方法就会很安全了。
Listing 2.7: The RequestFacade class 

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对象但是立即交给了private的ServletRequest对象的引用。注意每个在RequestFacade类的方法是调用的ServeletRequest对象对应的方法。

同样的ResponseFacade的实现也和RequestFacade的一样。

应用2中的类:

 HttpServer2
 Request
 Response
 StaticResourceProcessor
 ServletProcessor2
 Constants

HttpServer2类除了它使用了ServletProcessor2的await方法,其它跟HttpServer1类似。
if (request.getUri().startWith("/servlet/")) {
servletProcessor2 processor = new ServletProcessor2(); 
processor.process(request, response); 
} else {
 ... 
}


ServletProcessor2类的以下代码与ServletProcessor1不一样,其它都类似。
Servlet servlet = null; 
RequestFacade requestFacade = new RequestFacade(request);
ResponseFacade responseFacade = new ResponseFacade(response); 
try {
servlet = (Servlet) myClass.newInstance(); 
servlet.service((ServletRequest) requestFacade, (ServletResponse) responseFacade); 
}

运行这个应用。可以得到与前一个Application1一样的结果。
                                                        
                                                                                  第二章 完

你可能感兴趣的:(tomcat,工作,servlet,Access)