分享
 
 
 

Servlet容器的工作原理(三)

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

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 运行工作原理 随后的章节会告诉您怎样来解决这个问题。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有