设为首页 收藏本站
查看: 671|回复: 0

[经验分享] Tomcat源码学习(11)-How Tomcat works(转)

[复制链接]

尚未签到

发表于 2015-8-10 11:43:34 | 显示全部楼层 |阅读模式
ServletProcessor1类
     Listing 2.6中的ex02.pyrmont.ServletProcessor1类用于处理servlet的HTTP请求。
         Listing 2.6: ServletProcessor1类
package ex02.pyrmont;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandler;
import java.io.File;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ServletProcessor1 {
     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
             URL[] urls = new URL[1];
             URLStreamHandler streamHandler = null;
             File classPath = new File(Constants.WEB_ROOT);
             // the forming of repository is taken from the
             // createClassLoader method in
             // org.apache.catalina.startup.ClassLoaderFactory
             String repository =(new URL("file", null, classPath.getCanonicalPath() +
                 File.separator)).toString() ;
             // the code for forming the URL is taken from
             // the addRepository method in
             // org.apache.catalina.loader.StandardClassLoader.
             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 (ClassNotFoundException 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());
         }
     }
}
     ServletProcessor1类出奇的简单,仅仅由一个方法组成:process。这个方法接受两个参数:一个
javax.servlet.ServletRequest实例和一个javax.servlet.ServletResponse实例。该方法从ServletRequest中通过调用getRequestUri方法获得URI:
String uri = request.getUri();
     请记住URI是以下形式的:
/servlet/servletName
     在这里servletName是servlet类的名字。
     要加载servlet类,我们需要从URI中知道servlet的名称。我们可以使用process方法的下一行来获得servlet的名字:
String servletName = uri.substring(uri.lastIndexOf("/") + 1);
     接下去,process方法加载servlet。要完成这个,你需要创建一个类加载器并告诉这个类加载器要加载的类的位置。对于这个servlet容器,类加载器直接在Constants指向的目录里边查找。WEB_ROOT就是指向工作目录下面的webroot目录。
     注意: 类加载器将在第8章详细讨论。
     要加载servlet,你可以使用java.net.URLClassLoader类,它是java.lang.ClassLoader类的一个直接子类。一旦你拥有一个URLClassLoader实例,你使用它的loadClass方法去加载一个servlet类。现在举例说明URLClassLoader类是straightforward直接转发的。这个类有三个构造方法,其中最简单的是:
public URLClassLoader(URL[] urls);
     这里urls是一个java.net.URL的对象数组,这些对象指向了加载类时候查找的位置。任何以/结尾的URL都假设是一个目录。否则,URL会Otherwise, the URL假定是一个将被下载并在需要的时候打开的JAR文件。
     注意:在一个servlet容器里边,一个类加载器可以找到servlet的地方被称为资源库(repository)。
     在我们的应用程序里边,类加载器必须查找的地方只有一个,如工作目录下面的webroot目录。因此,我们首先创建一个单个URL组成的数组。URL类提供了一系列的构造方法,所以有很多中构造一个URL对象的方式。对于这个应用程序来说,我们使用Tomcat中的另一个类的相同的构造方法。这个构造方法如下所示。
public URL(URL context, java.lang.String spec, URLStreamHandler hander)
throws MalformedURLException
     你可以使用这个构造方法,并为第二个参数传递一个说明,为第一个和第三个参数都传递null。不过,这里有另外一个接受三个参数的构造方法:
public URL(java.lang.String protocol, java.lang.String host,
     java.lang.String file) throws MalformedURLException
     因此,假如你使用下面的代码时,编译器将不会知道你指的是那个构造方法:
new URL(null, aString, null);
     你可以通过告诉编译器第三个参数的类型来避开这个问题,例如。
URLStreamHandler streamHandler = null;
new URL(null, aString, streamHandler);
     你可以使用下面的代码在组成一个包含资源库(servlet类可以被找到的地方)的字符串,并作为第二个参数,
String repository = (new URL("file", null,
classPath.getCanonicalPath() + File.separator)).toString() ;
     把所有的片段组合在一起,这就是用来构造适当的URLClassLoader实例的process方法中的一部分:
// create a URLClassLoader
URL[] urls = new URL[1];
URLStreamHandler streamHandler = null;
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);
     注意: 用来生成资源库的代码是从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类加载器的实例, 把它向下转换(downcast)为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());
}
运行应用程序
     要在Windows上运行该应用程序,在工作目录下面敲入以下命令:
java -classpath ./lib/servlet.jar;./ ex02.pyrmont.HttpServer1
     在Linux下,你使用一个冒号来分隔两个库:
java -classpath ./lib/servlet.jar:./ ex02.pyrmont.HttpServer1
     要测试该应用程序,在浏览器的地址栏或者网址框中敲入:
http://localhost:8080/index.html
     或者
http://localhost:8080/servlet/PrimitiveServlet
     当调用PrimitiveServlet的时候,你将会在你的浏览器看到下面的文本:
Hello. Roses are red.
     请注意,因为只是第一个字符串被刷新到浏览器,所以你不能看到第二个字符串Violets are blue。我们将在第3章修复这个问题。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-96939-1-1.html 上篇帖子: 设置virgo-tomcat-server的JVM内存 下篇帖子: Jboss/Tomcat配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表