ServletProcessor1?類(lèi)?
ServletProcessor1?類(lèi)用來(lái)處理對(duì)?servlet?的?HTTP?請(qǐng)求。?它非常簡(jiǎn)單,只包含了一個(gè)?process?方法。?而這個(gè)方法接受兩個(gè)參數(shù):?一個(gè)javax.servlet.ServletRequest?實(shí)例和一個(gè)?avax.servlet.ServletResponse實(shí)例。?process?方法也構(gòu)建了一個(gè)?java.net.URLClassLoader?對(duì)象并使用它裝載?servlet?類(lèi)文件。?在從類(lèi)裝載器獲得的?Class?對(duì)象上,process?方法創(chuàng)建一個(gè)?servlet?實(shí)例并調(diào)用它的?service?方法。?
process?方法?
Listing?2.4.?ServletProcessor1?類(lèi)中?process?方法?
public?void?process(Request?request,?Response?response)?{
????String?uri????????????=?request.getUri();
????String?servletName????=?uri.substring(uri.lastIndexOf("/")?+?1);????URLClassLoader?loader?=?null;
????try?{????????
//?create?a?URLClassLoader
????????URLStreamHandler?streamHandler?=?null;
????????URL[]?urls????????=?new?URL[1];
????????File?classPath????=?new?File(Constants.WEB_ROOT);
????????String?repository?=?(new?URL("file",?null,?????????????classPath.getCanonicalPath()?+?File.separator)).toString();
????????urls[0]???????????=?new?URL(null,?repository,?streamHandler);
????????loader????????????=?new?URLClassLoader(urls);
????}????catch?(IOException?e)?{
????????System.out.println(e.toString());
????}????Class?myClass?=?null;
????try?{
????????myClass?=?loader.loadClass(servletName);
????}????catch?(Exception?e)?{
????????System.out.println(e.toString());
????}????Servlet?servlet?=?null;
????try?{
????????servlet?=?(Servlet)?myClass.newInstance();
????????servlet.service((ServletRequest)?request,?(ServletResponse)?response);
????}????catch?(Exception?e)?{
????????System.out.println(e.toString());
????}????catch?(Throwable?e)?{
????????System.out.println(e.toString());
????}
}process方法接受兩個(gè)參數(shù):一個(gè)?ServletRequest實(shí)例和一個(gè)?ServletResponse?實(shí)例。process方法通過(guò)調(diào)用?getRequestUri?方法從?ServletRequest獲取?URI。?
String?uri?=?request.getUri();切記?URI?的格式:?
/servlet/servletName?servletName是servlet類(lèi)的名稱(chēng)。?
如果要裝載?servlet?類(lèi),則需要使用以下代碼從?URI?獲知?servlet?名稱(chēng):String?servletName?=?uri.substring(uri.lastIndexOf("/")?+?1);然后?process?方法裝載?servlet。要做到這些,需要?jiǎng)?chuàng)建一個(gè)類(lèi)裝載器,并告訴裝載器該類(lèi)的位置,?該?servlet?容器可以指引類(lèi)裝載器在?Constants.WEB_ROOT?指向的目錄中查找。?在工作目錄下,WEB_ROOT?指向?webroot/?目錄。?
如果要裝載一個(gè)?servlet,則要使用?java.net.URLClassLoader?類(lèi),它是java.lang.ClassLoader?的間接子類(lèi)。?一旦有了?URLClassLoader?類(lèi)的實(shí)例,就可以使用?loadClass?方法來(lái)裝載一個(gè)?servlet?類(lèi)。?實(shí)例化?URLClassLoader?是很簡(jiǎn)單的。?該類(lèi)有三個(gè)構(gòu)建器,最簡(jiǎn)單的是:?
public?URLClassLoader(URL[]?urls);?urls?是一組指向其位置?java.net.URL?對(duì)象,?當(dāng)裝載一個(gè)類(lèi)時(shí)它會(huì)自動(dòng)搜索其位置。任一以?/?結(jié)尾的?URL?都被假定為一目錄,?否則,就假定其為?.jar?文件,在需要時(shí)可以下載并打開(kāi)。?
在一個(gè)?servlet?容器內(nèi),類(lèi)裝載器查找?servlet?類(lèi)的位置稱(chēng)為儲(chǔ)存庫(kù)?(repository)。在所舉的應(yīng)用程序中,類(lèi)裝載器只可在當(dāng)前工作目錄下的?webroot/?目錄查找,所以,首先得創(chuàng)建一組簡(jiǎn)單的?URL。?URL?類(lèi)提供了多個(gè)構(gòu)建器,因此有許多的方法來(lái)構(gòu)建一個(gè)URL?對(duì)象。?在這個(gè)應(yīng)用程序內(nèi),使用了和?TOMCAT?內(nèi)另外一個(gè)類(lèi)所使用的相同的構(gòu)建器。?該構(gòu)建器頭部?(signature)?如下:?
public?URL(URL?context,?String?spec,?URLStreamHandler?hander)?
throws?MalformedURLException?
可以通過(guò)傳遞給第二個(gè)參數(shù)一個(gè)規(guī)范,傳遞給第一個(gè)和第三個(gè)參數(shù)?null?值來(lái)使用這個(gè)構(gòu)建器,?但在些有另外一種可接受三個(gè)參數(shù)的構(gòu)建器:?
public?URL(String?protocol,?String?host,?String?file)?
throws?MalformedURLException?
因此,如果只寫(xiě)了以下代碼,編譯器將不知道是使用的哪個(gè)構(gòu)建器:?
new?URL(null,?aString,?null);?
當(dāng)然也可以能過(guò)告訴編譯器第三個(gè)參數(shù)的類(lèi)型來(lái)避開(kāi)這個(gè)問(wèn)題,如:?
URLStreamHandler?streamHandler?=?null;?
new?URL(null,?aString,?streamHandler);?
對(duì)于第二個(gè)參數(shù),可以傳遞包含儲(chǔ)存庫(kù)?(repository)?的?String?。?以下代碼可創(chuàng)建:?
String?repository?=?(new?URL("file",?null,?
classPath.getCanonicalPath()?+?File.separator)).toString();?
結(jié)合起來(lái),以下是構(gòu)建正確?URLClassLoader?實(shí)例的?process?方法的部分代碼?
//?create?a?URLClassLoader
URLStreamHandler?streamHandler?=?null;
URL[]?urls????????=?new?URL[1];
File?classPath????=?new?File(Constants.WEB_ROOT);
String?repository?=?(new?URL("file",?null,?????classPath.getCanonicalPath()?+?File.separator)).toString()?
urls[0]???????????=?new?URL(null,?repository,?streamHandler);
loader????????????=?new?URLClassLoader(urls);創(chuàng)建儲(chǔ)存庫(kù)?(repository)的代碼摘自org.apache.catalina.startup.ClassLoaderFactory內(nèi)的?createClassLoader?方法,而創(chuàng)建?URL?的代碼摘自org.apache.catalina.loader.StandardClassLoader?類(lèi)內(nèi)的?addRepository?方法。?但在此階段您還沒(méi)有必要去關(guān)心這些類(lèi)。?
有了類(lèi)裝載器,您可以使用loadClass方法裝載servlet類(lèi):?
Class?myClass?=?null;
try?{
????myClass?=?loader.loadClass(servletName);
????}catch?(ClassNotFoundException?e)?{
????System.out.println(e.toString());
}然后,process方法創(chuàng)建已裝載的?servlet類(lèi)的實(shí)例,傳遞給?javax.servlet.Servlet?,并激活?servlet?的?service?方法:?
Servlet?servlet?=?null;
try?{
????servlet?=?(Servlet)?myClass.newInstance();
????servlet.service((ServletRequest)?request,?(ServletResponse)?response);
}catch?(Exception?e)?{
????System.out.println(e.toString());
}catch?(Throwable?e)?{
????System.out.println(e.toString());
}編譯并運(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.HttpServer1?在?linux?環(huán)境下,使用冒號(hào)來(lái)隔開(kāi)類(lèi)庫(kù):?
java?-classpath?./lib/servlet.jar:./?ex02.pyrmont.HttpServer1?如果要測(cè)試該應(yīng)用程序,請(qǐng)?jiān)?URL?或?yàn)g覽器地址欄鍵入以下命令:?
http://localhost:8080/index.html?或者是:?
http://localhost:8080/servlet/PrimitiveServlet?您將會(huì)在瀏覽器中看到以下文本:?
Hello.?Roses?are?red.?
注意:您不能看到第二行字符?(Violets?are?blue),因?yàn)橹挥械谝恍凶址腿氲綖g覽器。?Tomcat?運(yùn)行工作原理?隨后的章節(jié)會(huì)告訴您怎樣來(lái)解決這個(gè)問(wèn)題。
posted on 2006-12-06 12:39
matthew 閱讀(270)
評(píng)論(0) 編輯 收藏 所屬分類(lèi):
JavaEE