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


Tomcat概述

1. Tomcat的总体架构

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

从上述知,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 ...%>
♦ 对于动作,格式为<jsp:include></jsp:include>,<jsp:useBean></jsp:useBean>,<jsp:setProperty/>,<jsp:getProperty/>,<jsp:forward></jsp:forward>,<jsp:attribute></jsp:attribute>,<jsp:plugin></jsp:plugin>
♦ 对于对象,脚本中内置了九大对象: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编译器详解

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

Ⅱ、语法树的遍历
对于语法树,最典型的处理模式就是访问者模式。它能很好的将将数据结构与处理相分离,提供很好的解耦作用。
经过语法解析及使用访问者模式将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工作原理


当客户端浏览器向服务器请求一个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就是要交互的具体对象,它们通常都作为运输工具来传递交互结果。


参考文章:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容