`

jsp/servlet 本质

 
阅读更多

 

1.  JSP与servlet

 

servlet是含有html的java代码,jsp是含有java代码的html页面!先出现的是servlet后出现jsp,jsp是为了解决servlet的输出问题而诞生!但是jsp却无法去除并替代servlet!他们的地位是平起平坐的!

可以这样说jsp 不过是编写servlet的一种方式而已,同时jsp最终还是要被翻译为servlet的。servlet会被编译(同java代码相同,其实它就是java代码),在请求期间,运行的是servlet,而非jsp!

jsp注重的是“简化html的创建和维护”,servlet注重的是“调用商业逻辑、执行复杂操作”。通常面向处理的任务servlet是最佳选择,而面向表示的任务jsp是最佳选择!通常一个项目中,最好的做法是将二者结合起来使用。可以这样讲:没有一个项目是全部使用jsp或者servlet来开发的!

 

2.  Servlet生命周期

servlet版本2.3

servlet有良好的生存期的定义,包括如何加载、实例化、初始化、处理客户端请求以及如何被移除。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。
1、加载和实例化
容器负责加载和实例化一个servlet。实例化和加载可以发生在引擎启动的时候,也可以推迟到容器需要该servlet为客户请求服务的时候(由loadonstartup配置决定)。

1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。

2)它的值必须是一个整数,表示servlet应该被载入的顺序

2)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;

3)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。

4)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。

5)当值相同时,容器就会自己选择顺序来加载。

所以,<load-on-startup>x</load-on-startup>,中x的取值1,2,3,4,5代表的是优先级,而非启动延迟时间。

 

首先容器必须先定位servlet类,在必要的情况下,容器使用通常的Java类加载工具加载该servlet,可能是从本机文件系统,也可以是从远程文件系统甚至其它的网络服务。容器加载servlet类以后,它会实例化该类的一个实例。需要注意的是可能会实例化多个实例,例如一个servlet类因为有不同的初始参数而有多个定义,或者servlet实现SingleThreadModel而导致容器为之生成一个实例池(所谓实例池,维护多个实例的池子!)。到目前为止,我小崔还一直是用一个实例完成开发!

2、初始化
servlet加载并实例化后,容器必须在它能够处理客户端请求前初始化它。初始化的过程主要是读取永久的配置信息,昂贵资源(例如JDBC连接)以及其它仅仅需要执行一次的任务。通过调用它的init方法并给它传递唯一的一个(每个servlet定义一个)ServletConfig对象完成这个过程。给它传递的这个配置对象允许servlet访问容器的配置信息中的名称-值对(name-value)初始化参数。这个配置对象同时给servlet提供了访问实现了ServletContext接口的具体对象的方法,该对象描述了servlet的运行环境。
    2.1初始化的错误处理
    在初始化期间,servlet实例可能通过抛出UnavailableException 或者 ServletException异常表明它不能进行有效服务。如果一个servlet抛出一个这样的异常,它将不会被置入有效服务并且应该被容器立即释放。在此情况下destroy方法不会被调用因为初始化没有成功完成。在失败的实例被释放后,容器可能在任何时候实例化一个新的实例,对这个规则的唯一例外是如果失败的servlet抛出的异常是UnavailableException并且该异常指出了最小的无效时间,那么容器就会至少等待该时间指明的时限才会重新试图创建一个新的实例。
    2.2、工具因素
    当工具(注:根据笔者的理解,这个工具可能是应用服务器的某些检查工具,通常是验证应用的合法性和完整性)加载和内省(introspect)一个web应用时,它可能加载和内省该应用中的类,这个行为将触发那些类的静态初始方法被执行,因此,开发者不能假定只要当servlet的init方法被调用后它才处于活动容器运行状态(active container runtime)。作为一个例子,这意味着servlet不能在它的静态(类)初始化方法被调用时试图建立数据库连接或者连接EJB容器。

3、处理请求
在servlet被适当地初始化后,容器就可以使用它去处理请求了。每一个请求由ServletRequest类型的对象代表,而servlet使用ServletResponse回应该请求。这些对象被作为service方法的参数传递给servlet。在HTTP请求的情况下,容器必须提供代表请求和回应的HttpServletRequest和HttpServletResponse的具体实现。需要注意的是容器可能会创建一个servlet实例并将之放入等待服务的状态,但是这个实例在它的生存期中可能根本没有处理过任何请求。
    3.1、多线程问题
    容器可能同时将多个客户端的请求发送给一个实例的service方法,这也就意味着开发者必须确保编写的servlet可以处理并发问题。如果开发者想防止这种缺省的行为,那么他可以让他编写的servlet实现SingleThreadModel。实现这个类可以保证一次只会有一个线程在执行service方法并且一次性执行完。容器可以通过将请求排队(使用锁机制)或者维护一个servlet实例池(singleThreadMode或者其他方式)满足这一点。如果servlet是分布式应用的一部分,那么,那么容器可能在该应用分布的每个JVM中都维护一个实例池。如果开发者使用synchronized关键字定义service方法(或者是doGet和doPost),容器将排队处理请求,这是由底层的java运行时系统要求的。我们强烈推荐开发者不要同步service方法或者HTTPServlet的诸如doGet和doPost这样的服务方法。
    3.2、处理请求中的异常
    servlet在对请求进行服务的时候有可能抛出ServletException或者UnavailableException异常。ServletException表明在处理请求的过程中发生了错误容器应该使用合适的方法清除该请求。UnavailableException表明servlet不能对请求进行处理,可能是暂时的,也可能是永久的。如果UnavailableException指明是永久性的,那么容器必须将servlet从服务中移除,调用它的destroy方法并释放它的实例。如果指明是暂时的,那么容器可以选择在异常信息里面指明的这个暂时无法服务的时间段里面不向它发送任何请求。在这个时间段里面被被拒绝的请求必须使用SERVICE_UNAVAILABLE (503)返回状态进行响应并且应该携带稍后重试(Retry-After)的响应头表明不能服务只是暂时的。容器也可以选择不对暂时性和永久性的不可用进行区分而全部当作永久性的并移除抛出异常的servlet。
    3.3线程安全
    开发者应该注意容器实现的请求和响应对象(注:即容器实现的HttpServletRequest和HttpServletResponese)没有被保证是线程安全的,这就意味着他们只能在请求处理线程的范围内被使用,这些对象不能被其它执行线程所引用,因为引用的行为是不确定的。

4、服务结束
容器没有被要求将一个加载的servlet保存多长时间,因此一个servlet实例可能只在容器中存活了几毫秒,当然也可能是其它更长的任意时间(但是肯定会短于容器的生存期)
当容器决定将之移除时(原因可能是保存内存资源或者自己被关闭),那么它必须允许servlet释放它正在使用的任何资源并保存任何永久状态(这个过程通过调用destroy方法达到)。容器在能够调用destroy方法前,它必须允许那些正在service方法中执行的线程执行完或者在服务器定义的一段时间内执行(这个时间段在容器调用destroy之前)。一旦destroy方法被调用,容器就不会再向该实例发送任何请求。如果容器需要再使用该servlet,它必须创建新的实例。destroy方法完成后,容器必须释放servlet实例以便它能够被垃圾回收。

 

3.  线程安全

 

很多情况下,可能会有很多并发的请求,为了提高运行效率,节省内存资源,容器采用Thread Pool.

一般情况下容器只对每个servlet生成一个实例,让他服务于所有的请求,对于客户端同时请求一个servlet,他们是被并发的处理的,并不是等上一个请求处理完成再处理下一个。如果两个请求同时到达,那么他们处理完成的时间也是差不多的。

 

 

当然有些时候处于并发的同步性考虑,servlet并不适合多线程,那么就可以通过继承标识接口 SingleThreadModel来实现。这样的话servlet就不会被多线程执行,而是生成他的多个实例来提高性能(注意不是一个);单线程servlet仅仅表示他不会被多线程执行,并不能说明它是线程安全的。

Note:

单实例多线程和单线程servlet具体区别:

多线程情况下每个线程会保存实例中的局部变量的一个copy,对局部变量的修改只会影响自己的copy不会影响别的线程,所以局部变量是安全的。但是对于全局变量,是属于所有线程的。对他的修改会影响到其他的线程。

而对于单线程servlet,会有多个实例,这些实例的变量都是属于自己的,可能是线程安全的(原因是之前使用过的实例会被放入到实例池中,它可能会被下次请求使用),局部的变量是线程安全的;

但是在这两种情况下static变量都不是线程安的。

 

也可以通过Synchronizing servlet的service()方法来实现同步,但是这种方法不是很有效,比起SingleThreadModel方式来效率要低,所以很少用。原因是,这种方式的servlet在容器中只存在一个实例,而对于SingleThreadModel方式的会有多个实例同时存在,当然效率上会有差别。

对于Context,Session,Request的线程安全问题:

毫无疑问Context不是线程安全的,而对于Session呢?Session是被正在处理属于这个Session的线程来访问的,安理说他只会同时被一个线程访问,应该是线程安全的。但是也有特殊情况,如果一个客户同时开了多个窗口来同时提交请求的,还会出现多个线程同时访问一个Session的情况。Request是线程安全的。

小结:

1.设计servlet的时候要考虑线程安全的问题。

2.对于单线程servlet,要通过SingleThreadModel来实现,不要通过Synchronizing来实现。

3.SingleThreadModel并不能保证线程安全,他只保证不被多线程执行。

4.对于Context,Session的数据修改要考虑同步。或者其他方式来避免线程安全问题。

5.Servlet中可以把不变常量写成全局,或者静态。

6.对于不想被其他线程共同访问的变量要写成局部变量。保证安全。

  • 大小: 45 KB
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    JSP/Servlet Java面试逻辑题

    答:JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。JSP编译后是类servlet。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来...

    网上书店系统(jsp+servlet+sqlserver)

    系统平台介绍:适合作为毕业设计...Struts实质上就是在JSP的基础上实现的一个MVC框架。在Struts框架中,模型由实现业务逻辑的Javabean组件构成,控制器由Servlet来实现,视图由一组Jsp文件构成]。是java毕业设计的首选

    Jsp+JavaBean循序渐进教程+Servlet工作原理实例

    JSP+JavaBean+Servlet三层结构的实质是多了一个Controller:Servlet来分发客户端浏览器的请求。如果把起控制器作用的Servlet的作用理解为对客户端的请求进行预处理对理解Servlet将有很大的帮助。通过web.XML配置文件...

    Java学习指南(6) 网站入门篇 JavaEE / Servlet

    * JSP的使用和本质原理 * 一个图片库管理系统,综合运用了REST, JDBC和文件上传技术 三、课程体系〖Java学习指南系列〗:包含入门与进阶语法,Swing桌面开发,安卓开发,JavaFX开发,网络通信Socket,数据结构与...

    在线拍卖系统,java+jsp+servlet+mysql+ajax+css+js

    本项目设计一个消费者对消费者(C2C)模式的网上拍卖网站,通过拍卖过程的实践,深刻了解电子商务C2C模式的内涵和本质,掌握电子商务网站开发的技术。整个系统包括会员注册、信息发布功能、物品拍卖、竞价购买、拍卖...

    jsp经典笔记jsp经典笔记

    JSP(java server page) 1.JSP介绍: JSP是服务器端运行的页面,JSP本身就是一个Servlet,他不仅可以包含静态的HTML代码,也可以包含动态的JAVA代码,...3,JSP本质上就是一个Servlet 4,JSP是以静态页面为主的。

    javaEE servlet 学习笔记

    jsp本质上是servlet,但是为了更加符合mvc的框架,将页面显示和逻辑控制分离,jsp页面只负责页面,也就是mvc中的V(view),而servlet负责mvc中的C(control)。 而为了更加好的理解结构,一下先说明一下mvc框架。 M...

    java面试题

    JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。JSP编译后是"类servlet"。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而...

    java面试题自己总结的ssh较多

    1.Jsp经编译后成为servlet,(jsp本质上就是servlet类,jvm只能识别java类,不能识别jsp的代码,web容器将jsp的代码编译成jvm能识别的java 类) 2.Jsp更擅长页面显示,servlet更擅长与逻辑控制。 3.Servlet中没有内置...

    【计算机课程作业/毕设】JSPSmart系统-考试管理及成绩查询模块的设计与开发(源代码+论文)资源

    下图显示了JSP容器初次执行JSP的过程:尽管JSP在本质上是Servlet,但这两者的创建方式不一样。Servelet完全由java程序代码构成,擅长于流程控制和事务处理,而通过Servlet来生成动态网页很不直观;JSP由HTML代码和...

    servlet详细介绍过滤器控制权限等

    在学习完javase部分,在进入web编程的时候,有人也许会建议去学习jsp,但是我建议还是先学习servlet,因为jsp的本质就是servlet,如果能很好的了解servlet,我想对你以后学习java web编程会有很大的帮助的...

    Jsp-note.doc

    对jsp的简单笔记 一:JSP 简介java server page ...Servlet 生成静态页面比较麻烦,适合于做control层,JSP生成页面比较容易,适合做view 层,JSP本质上就是servlet. (1) 目录结构与servlet 相同。

    J2EE体系之-JSP学习

    JSP本质就是一个文档,他不仅可以包含静态的HTML代码,也可以包含动态的JAVA代码,服务器容器可以将JSP转换成Servlet发布,并接受请求 JSP文件只需放在应用文件下就可以了 JSP例子: &lt;title&gt;time&lt;/...

    JAVAEE中Servlet实例Response与Request对象方法调用范例

    jsp本质上是servlet,但是为了更加符合mvc的框架,将页面显示和逻辑控制分离,jsp页面只负责页面,也就是mvc中的V(view),而servlet负责mvc中的C(control)。

    jsp,el,jstl笔记总结

    2.jsp运行原理-----jsp本质就是servlet(面试) jsp在第一次被访问时会被Web容器翻译成servlet,在执行 过程: 第一次访问----&gt;helloServlet.jsp----&gt;helloServlet_jsp.java----&gt;编译运行 PS:被翻译后的...

    JSP定制标实例

    JSP标签在JSP页面中通过XML语法格式被调用,当JSP引擎将JSP页面翻译成Servlet时,就将这些调用转换成相应的Java代码。本质上,JSP标签调用了部分Java代码,只是这些Java代码在JSP页面中以另外一种形式(XML语法格式...

    javaWeb知识点总结—— 关乎JSP、JSTL、Filter、Listener的知识(含详细思维导图)

    在最早期是没有JSP的,那么后端开发人员想要展示一个网页,就是在Servlet中 拼接html. 于是就有了JSP, 但是JSP不是一门新的技术,他的本质上还是Servlet, 意思是服务器还是会将 JSP 转成Java代码,在Java代码中,...

    JSP运行原理和九大隐式对象说明

    JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用。 由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有...

    JSP动态网页开发技术概述

     JSP(Java Server Pages)是建立在Servlet规范之上的动态网页开发技术,其实质是一个简化的Servlet。在JSP文件中,HTML和Java代码共同存在,其中,HTML代码用于实现网页中静态内容的显示,Java代码用于实现网页中...

    18-el&jstl源代码.rar

    2.jsp运行原理-----jsp本质就是servlet(面试) 3.jsp指令(3个) 4.jsp内置/隐式对象(9个)----- 笔试 5.jsp标签(动作) 1.EL 表达式概述 2.EL从域中取出数据(EL最重要的作用) 3.EL的内置对象11个 4.EL...

Global site tag (gtag.js) - Google Analytics