Application?2?
第一個(gè)應(yīng)用程序里存在一個(gè)值得注意的問題。?在ServletProcessor1?類的?process?方法里,上溯?(upcast)ex02.pyrmont.Request?實(shí)例到?javax.servlet.ServletRequest,將其作為第一個(gè)參數(shù)傳遞給?servlet?的?service?方法。另上溯(upcast)?ex02.pyrmont.Response?實(shí)例到?javax.servlet.ServletResponse?,并將其作為第二個(gè)參數(shù)傳遞給?servlet?的?service?方法。?
try?{
???servlet?=?(Servlet)?myClass.newInstance();
???servlet.service((ServletRequest)?request,?(ServletResponse)?response);
}這樣會(huì)使安全性能大打折扣。?知道?servlet?容器工作原理的程序員可以將?ServletRequest?和?ServletResponse?實(shí)例向下轉(zhuǎn)型?(downcast)?到Request?和?Response?,并調(diào)用它們的?public?方法。?Request?實(shí)例能調(diào)用它的?parse?方法;?Request?實(shí)例能調(diào)用它的?sendStaticResource?方法。?
可以將?parse?和?sendStaticResource?方法設(shè)為?private,因?yàn)樵?ex02.pyrmont?里將會(huì)從其他類里調(diào)用它們。?然而,這兩個(gè)方法在?servlet?內(nèi)應(yīng)該是不可用的。?一個(gè)解決方法是:給?Request?和?Response?類一個(gè)默認(rèn)的訪問修飾符,以致他們?cè)?ex02.pyrmont?外不能被使用。?但還有一個(gè)更好的解決方法:?使用?facade?類。?
在第二個(gè)應(yīng)用程序內(nèi),添加兩個(gè)?facade?類:RequestFacade?和?ResponseFacade。?RequestFacade?類實(shí)現(xiàn)?ServletRequest?接口,并通過傳遞?Request?實(shí)例來實(shí)例化,?Request?實(shí)例將在?ServletRequest?對(duì)象的構(gòu)建器里被引用?。?ServletRequest?對(duì)象本身是?private?類型的,不能在類之外訪問。就構(gòu)建?RequestFacade?對(duì)象,并將其傳遞給?service?方法,而不上溯?(upcast)?Request?對(duì)象給?ServletRequest,并將其傳遞給?service?方法。?servlet?程序員仍舊可以向下轉(zhuǎn)型?(downcast)?ServletRequest?到?RequestFacade,但是,只要訪問?ServletRequest?接口的可用方法就可以了。現(xiàn)在,parseUri?就安全了。?
Listing?2.5?顯示?RequestFacade?類部分代碼:?
Listing?2.5.?RequestFacade?類?
package?ex02.pyrmont;
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);
????}
????public?Enumeration?getAttributeNames()?{
????????return?request.getAttributeNames();
????}
????...
}注意?RequestFacade?構(gòu)造函數(shù)。?它會(huì)接受一個(gè)?Request?對(duì)象,即刻分配給私有的?servletRequest?對(duì)象引用。?還要注意,RequestFacade?內(nèi)的每個(gè)方法調(diào)用?ServletRequest?對(duì)象內(nèi)相應(yīng)的方法。?
ResponseFacade?類也是如此。?
以下是?application?2?所包含的類?
HttpServer2
Request?
Response?
StaticResourceProcessor?
ServletProcessor2?
Constants?HttpServer2?類類似于?HttpServer1,
只是它在?await?方法內(nèi)使用了?ServletProcessor2?而不是ServletProcessor1。
if?(request.getUri().startsWith("/servlet/"))?{
???ServletProcessor2?processor?=?new?ServletProcessor2();
???processor.process(request,?response);
}else?{
????...
??????}
ServletProcessor2?類也類似于?ServletProcessor1,
只是在以下?process?方法的部分代碼有點(diǎn)不同:
Servlet?servlet?=?null;
RequestFacade?requestFacade???=?new?RequestFacade(request);
ResponseFacade?responseFacade?=?new?ResponseFacade(response);
try?{
????servlet?=?(Servlet)?myClass.newInstance();
????servlet.service((ServletRequest)?requestFacade,(ServletResponse)?responseFacade);
}編譯并運(yùn)行該應(yīng)用程序?
如果要編譯該應(yīng)用程序,在工作目錄下鍵入以下命令:?
javac?-d?.?-classpath?./lib/servlet.jar?src/ex02/pyrmont/*.java?如果要在?windows?下運(yùn)行該應(yīng)用程序,在工作目錄下鍵入以下命令:?
java-classpath?./lib/servlet.jar;./?ex02.pyrmont.HttpServer2?在linux環(huán)境下,使用分號(hào)來隔開類庫:?
java?-classpath?./lib/servlet.jar:./?ex02.pyrmont.HttpServer2?您可以使用和?application?1?相同的?URL?以收到同樣的結(jié)果。?
總結(jié)?
本文討論了簡(jiǎn)單的能夠用于服務(wù)靜態(tài)資源,以及處理如?PrimitiveServlet?一樣簡(jiǎn)單的?servlet?的?servlet?容器。?同時(shí)也提供?javax.servlet.Servlet?的背景信息。?
posted on 2006-12-06 12:40
matthew 閱讀(355)
評(píng)論(0) 編輯 收藏 所屬分類:
JavaEE