jsp 在tomcat中的处理流程的一小部分

1.在Tomcat的公共设定中
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
........................
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
可以看出*.jsp文件都是请求org.apache.jasper.servlet.JspServlet得。

2.下面再看看org.apache.jasper.servlet.JspServlet中做什么。
从源代码中可以看出,这个类是继承HttpServlet类,并覆盖了主要方法
public void service (HttpServletRequest request, 
HttpServletResponse response)
throws ServletException, IOException {
在这个方法中找到jsp文件的路径jspUri,并执行方法serviceJspFile
接着在方法serviceJspFile中我们看到它新创建了一个类JspServletWrapper的实例,并执行了这个类实例的service方法。

3.接下来,我们再看看这个类org.apache.jasper.servlet.JspServletWrapper
在这个类中
我们可以看到在初始化的时候,创建了一个新的对象
ctxt = new JspCompilationContext(jspUri, tagInfo, options,
servletContext, this, rctxt,
tagFileJarUrl);
找到方法
public void service(HttpServletRequest request, 
HttpServletResponse response,
boolean precompile)
throws ServletException, IOException, FileNotFoundException
这里,使用了ctxt.compile(),对jsp文件进行了编译,
再调用方法getServlet();给Servlet类型对象theServlet赋值,
最后,调用theServlet的service方法。
由于从jsp转换来的java继承类HttpJspBase,我们可以从类HttpJspBase 中看到servcie方法又调用了_jspService方法,

这样最终调用了由jsp转换来的java中的_jspService方法

在这最底部的阀门里,其实就主要做了两件事:
 
   一是启动过滤器,让request在N个过滤器里面筛一通,如果OK! 那就PASS。 否则就跳到其他地方去了。
 
   二是servlet.service((HttpServletRequest) request,(HttpServletResponse) response); 这个方法.
 
     如果是JspServlet, 那么先把jsp文件编译成servlet_xxx, 再invoke servlet_xxx的servie()方法。
 
     如果是DefaultServlet, 就直接找到静态资源,取出内容, 发送出去。
 
     如果是InvokerServlet, 就调用那个具体的servlet的service()方法。
 
   ok! 完毕。


从功能的角度将Tomcat源代码分成5个子模块,它们分别是:

  1. Jsper子模块:这个子模块负责jsp页面的解析、jsp属性的验证,同时也负责将jsp页面动态转换为java代码并编译成class文件。在Tomcat源代码中,凡是属于org.apache.jasper包及其子包中的源代码都属于这个子模块;
  2. Servlet和Jsp规范的实现模块:这个子模块的源代码属于javax.servlet包及其子包,如我们非常熟悉的javax.servlet.Servlet接口、javax.servet.http.HttpServlet类及javax.servlet.jsp.HttpJspPage就位于这个子模块中;
  3. Catalina子模块:这个子模块包含了所有以org.apache.catalina开头的java源代码。该子模块的任务是规范了Tomcat的总体架构,定义了Server、Service、Host、Connector、Context、Session及Cluster等关键组件及这些组件的实现,这个子模块大量运用了Composite设计模式。同时也规范了Catalina的启动及停止等事件的执行流程。从代码阅读的角度看,这个子模块应该是我们阅读和学习的重点。
  4. Connectors子模块:如果说上面三个子模块实现了Tomcat应用服务器的话,那么这个子模块就是Web服务器的实现。所谓连接器(Connector)就是一个连接客户和应用服务器的桥梁,它接收用户的请求,并把用户请求包装成标准的Http请求(包含协议名称,请求头Head,请求方法是Get还是Post等等)。同时,这个子模块还按照标准的Http协议,负责给客户端发送响应页面,比如在请求页面未发现时,connector就会给客户端浏览器发送标准的Http 404错误响应页面。
  5. Resource子模块:这个子模块包含一些资源文件,如Server.xml及Web.xml配置文件。严格说来,这个子模块不包含java源代码,但是它还是Tomcat编译运行所必需的。

2.2 Tomcat运行流程

 

 

图2-2 tomcat运行流程

假设来自客户的请求为:http://localhost:8080/test/index.jsp

  1. 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
  2. Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应
  3. Engine获得请求localhost:8080/test/index.jsp,匹配它所有虚拟主机Host
  4. Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
  5. localhost Host获得请求/test/index.jsp,匹配它所拥有的所有Context
  6. Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)
  7. path="/test"的Context获得请求/index.jsp,在它的mapping table中寻找对应的servlet
  8. Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
  9. 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet.service()方法,service ()中调用 doGet或doPost方法
  10. Context把执行完了之后的HttpServletResponse对象返回给Host
  11. Host把HttpServletResponse对象返回给Engine
  12. Engine把HttpServletResponse对象返回给Connector
  13. Connector把HttpServletResponse对象返回给客户browser
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值