Jsp&Servlet工作原理详解(基于Tomcat容器)


Tomcat概述

1. Tomcat的总体架构

Jsp&Servlet工作原理详解(基于Tomcat容器)_第1张图片

Tomcat启动server服务器对外提供Service服务,Container作为Service的核心组件(Container可以连接多个Connector构成Service),有了Service就可以对外提供服务。
2. Tomcat容器模型

Jsp&Servlet工作原理详解(基于Tomcat容器)_第2张图片

从上述知,Service对外提供Web应用服务,而Service核心组件Container的灵魂便是Servlet容器。而真正管理Servlet的是Context容器。Context容器直接管理Servlet在容器中的包装类Wrapper,一个Web应用对应一个Context容器。添加一个Web应用就会创建一个Context容器,并将这个Context容器加入到父容器Host中。

JSP概述

1. JSP基本概念

JSP全称是Java ServerPages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。

2. 常见JSP语法

♦ 对于代码脚本,格式为<% java代码片段 %>;
♦ 对于变量声明,格式为<%! int i=0; %>;
♦ 对于表达式,格式为<%= 表达式 %>;
♦ 对于注释,格式为<%-- JSP注释 --%>/;
♦ 对于指令,格式为<%@page ...%>,<%@taglib ...%>,<%@include ...%>
♦ 对于动作,格式为,,,,,,
♦ 对于对象,脚本中内置了九大对象:request,response,out,session,config,application,Exception,pageContext,page
重点介绍几个对象:
▶ Exception对象:当jsp页面运行时发生了异常,容器会将异常信息封装到该对象,可以使用该对象提供的方法来输出异常的信息。另外,必须在页面设置isErrorPage="true"指令才能使用该隐含对象。
▶ pageContext对象:容器会为每一个JSP实例(JSP所对应的那个Servlet对象)创建唯一的一个符合pageContext接口的对象,称之为page上下文。该对象会一直存在,除非JSP实例被销毁。它作用:①绑定数据(绑定的数据只有对应的JSP实例才可以访问):setAttribute、removeAttribute、getAttribute。②找到其他八个隐含对象(详情看JSP标签)。
▶ config对象:即ServletConfig,可以使用该对象获得初始化参数。
▶ page对象:JSP实例本身(一般不用)。

3. JSP工作原理

客户端浏览器向服务器端发出request请求,服务端接受请求之后会先检查此JSP文件是否存在:
■ 若不存在,则直接报错;
■ 若存在,则接着检查所请求的这个JSP文件内容(代码)是否已经被更新,或者是否是JSP文件创建后的第一次被访问;
□ 如果是,那么这个JSP文件将会在服务器端的JSP引擎下转换成一个Servlet的java源文件;接着这个Servlet类会在java编译器的作用下被编译成字节码文件,并装载到JVM中去执行。
□ 如果不是,则直接由服务器端检索出它对应的Servlet实例来处理。
注意:JSP 文件不是在服务器启动的时候转换成 Servlet 类的。而是在被客户端访问的时候才可能发生转换的 ( 如 JSP 文件内容没有被更新等,就不再发生 Servlet 转换 )。

4. JSP编译器详解

Jsp&Servlet工作原理详解(基于Tomcat容器)_第3张图片

Ⅰ、语法树的生成
JasPer对JSP语法解析之后也会生成一棵树,这棵树中的各个节点保存了不同的信息,但对于JSP语法树来说比较简单,因为它只有一个父节点和N个子节点。
比如说图中node1节点中保存的数据就可能是类似于<%-- JSP注释 --%>这一类的注释节点;而node2结点就可能保存的是形如<%= 表达式 %>的表达式节点;其余的节点就存储JSP中其他的语法,有了这棵树就可以很方便我们构建出与之对应的Servlet。

Jsp&Servlet工作原理详解(基于Tomcat容器)_第4张图片

Ⅱ、语法树的遍历
对于语法树,最典型的处理模式就是访问者模式。它能很好的将将数据结构与处理相分离,提供很好的解耦作用。
经过语法解析及使用访问者模式将HelloWorld.jsp文件编译成相对应的HelloWorld_jsp.java文件,可以看到,Servlet类名由JSP文件名加_jsp拼成,类包名默认为org.apache.jsp。
JSP生成的JAVA类都必须继承org.apache.jasper.runtime.HttpJspBase。这个类的结构图如上所示,它继承HttpServlet是为了将HttpServlet中所有的功能都继承下来。另外,又实现HttpJSPPage接口,定义了一个JSP类的Servlet的核心处理方法_JspService。除此之外,还有_JspInit和_JspDestroy方法,它们分别用于JSP的初始化和销毁。这些方法都由Servlet的service、init、destroy方法间接调用,多以JSP生成Servlet主要就是实现这几个方法。通过JSP编译器编译后,生成了对应的JAVA文件,接下来就需要将JAVA文件编译成Class文件,可以直接使用Eclipse JDT编译器对其进行编译即可。

注意:JSP判断重新编译的条件的是什么?(重新编译指的是将JSP文件编译成JAVA再编译成Class)
答:当我们修改了某个JSP文件后或者某JSP文件引入的资源别修改后。所以最好的判断的标准就是某JSP或资源的最后修改时间——LastModified属性。


Servlet

1. Servlet基本概念
⑴、 Servlet是JavaWeb的三大组件之一,它属于动态资源。Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:1. 接收请求数据 2. 处理请求 3. 完成响应
⑵、实现Servlet的方式(由我们自己来编写)
实现Servlet有三种方式:
实现javax.servlet.Servlet接口;
继承javax.servlet.GenericServlet类;
继承javax.servlet.http.HttpServlet类;

2. Servlet的生命周期
① Servlet维基百科解释
♠ 当servlet被部署在应用服务器中(应用服务器中用于管理Java组件的部分被抽象成为容器)以后,由容器控制servlet的生命周期。
♠ 除非特殊制定,否则在容器启动的时候,servlet是不会被加载的,servlet只会在第一次请求的时候被加载和实例化。
♠ servlet一旦被加载,一般不会从容器中删除,直至应用服务器关闭或重新启动。但当容器做内存回收动作时,servlet有可能被删除。也正是因为这个原因,第一次访问servlet所用的时间要大大多于以后访问所用的时间。

3. Servlet的实例化过程
(1)加载和实例化
如果Servlet容器还没实例化一个Servlet对象,此时容器装载和实例化一个 Servlet。创建出该 Servlet 类的一个实例。如果已经存在一个Servlet对象,此时不再创建新实例。
(2)初始化
在Servlet被创建后,服务器会马上调用Servlet的void init(ServletConfig)方法。请记住,Servlet出生后马上就会调用init()方法,而且一个Servlet的一生。这个方法只会被调用一次。
(3)处理请求
当服务器每次接收到请求时,都会去调用Servlet的service()方法来处理请求。服务器接收到一次请求,就会调用service() 方法一次,所以service()方法是会被调用多次的。
(4)销毁
通常都是在服务器关闭时Servlet才会离去!在服务器被关闭时,服务器会去销毁Servlet,在销毁Servlet之前服务器会先去调用Servlet的destroy()方法,所以我们可以将一些资源释放的代码放入其中。
其中,(1)(2)(4) 在 Servlet 的整个生命周期中只会被执行一次。

4. Servlet工作原理

Jsp&Servlet工作原理详解(基于Tomcat容器)_第5张图片

当客户端浏览器向服务器请求一个Servlet时,服务器收到该请求后,首先到容器中检索与请求匹配的Servlet实例是否已经存在。
1、若不存在,则Servlet容器负责加载并实例化出该类Servlet的一个实例对象,接着容器框架负责调用该实例的init()方法来对实例做一些初始化工作,然后Servlet容器运行该实例的service()方法。
2、若存在,则容器框架直接调用该实例的service()方法。
在处理请求时:
1. Servlet容器会创建一个请求对象ServletRequst,其中封装了用户请求的信息,以便处理客户端请求,此外还会创建一个响应对象ServletResponse,用于响应客户端请求,想客户端返回数据。
2. 然后Servlet容器把创建好的ServletRequst和ServletResponse对象传给用户所请求的Servlet。
3. Servlet利用ServletResponse包含的数据和自身的业务逻辑处理请求,并把处理好的结果写在ServletResponse中,最后Servlet容器把响应结果传给用户。

5. Servlet接口相关类型
ServletRequest:service() 方法的参数,它表示请求对象,它封装了所有与请求相关的数据,它是由服务器创建的;
ServletResponse:service()方法的参数,它表示响应对象,在service()方法中完成对客户端的响应需要使用这个对象;
ServletConfig:init()方法的参数,它表示Servlet配置对象,它对应Servlet的配置信息,那对应web.xml文件中的元素。
ServletContext:Servlet的运行模式是一个典型的“握手型的交互式”运行模式。所谓“握手型的交互式”就是两个模块为了交换数据通常都会准备一个交易场景,这个场景一直跟随这个交易过程直到这次交易过程完成为止。这个场景的初始化是根据这次交易对象指定的参数来定制的。即交易场景就由ServletContext来描述,而定制的参数集合就由ServletConfig来描述,而ServletRequest和ServletResponse就是要交互的具体对象,它们通常都作为运输工具来传递交互结果。


参考文章:

  • JSP/Servlet工作原理
  • Servlet详解
  • 《深入分析JavaWeb技术内幕》

你可能感兴趣的:(Jsp&Servlet工作原理详解(基于Tomcat容器))