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