网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  servlet容器工作原理讲解(三)     
  文章作者:未知  文章来源:水木森林  
  查看:75次  录入:管理员--2007-11-17  
  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 urlclassloaderurlstreamhandler 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 运行工作原理 随后的章节会告诉您怎样来解决这个问题。

【关于作者】

本系列文章由petrel翻译,petrel ,java 爱好者,在深圳从事 java 和数据库的开发工作,喜爱各项运动!也可以点击http://www.matrix.org.cn/user_view.asp?username=petrel查看她的信息.或者通过petrel.zhang@ccjk.com 与她联系.

原文:】http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html
 
 
上一篇: servlet容器工作原理讲解(二)    下一篇: session(resin example)
  相关文档
java web server2.0 11-17
给 java se 注入脚本语言的活力 11-17
java操作excel完美解决方案 11-17
java 线程安全 11-17
apache动了java奶酪(news) 11-17
对openminer进行了一系列手术 11-17
java threading中的final变量 11-17
用 正则表达式 判断一个简单的用户登陆的例子 11-17
详解xml与j2ee组合技术的精髓(1) 11-16
常用几种禁止修改输入框的方法 11-17
实战角度比较ejb2和ejb3的架构异同 11-17
可用于 xml 和 web 服务的专业工具 11-17
jsp中在内存中生成的图片显示到页面中 11-17
ant 使得java jars打包变得简单和可靠 11-17
tostring 方法 11-16
pattens in java(中文) 11-17
- redirect printstacktrace() to a string 11-17
java的基本数据类型与流 11-17
java核心代码例程之:vectordemo.java 11-17
使用jsp的自定义标签开发 11-16
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息