SRV.2 The Servlet Interface
Servlet接口是Java Servlet API的核心抽象。所有servlet都直接或者间接地实现了这个接口,更为普遍的是,继承自一个实现了此接口的类。在Java Servlet API中有两个类,GenericServlet和HttpServlet,它们继承了Servlet接口。通常,开发者会继承HttpServlet来实现他们的servlet。
SRV.2.1 Request Handling Methods
基础的Servlet接口定义了一个service方法来处理客户端的request。Service方法在container把每个request路由至某个servlet实例时被调用。
对于web应用程序来说,并发request的处理通常需要web container开发者设计的serlvet可以在某个特定时刻于service方法内处理多线程的执行。
一般来说,web container对于同一个servlet处理并发requests,是通过在不同线程中同时执行service方法来实现的。
SRV.2.1.1 HTTP Specific Request Handling Method
HttpServlet的抽象子类与它相比,增加了额外的方法,这些方法会自动被service方法调用,如:
- doGet用来处理HTTP GET request
- doPost用来处理HTTP POST request
SRV.2.2 Number of Instances
作为servlet container的web application的deployment descriptor的一部分,servlet声明控制着container怎样提供servlet的实例。关于servlet declaration的详细信息,参见Chapter SRV.13 Deployment Descriptor。
在非分布式环境下,servlet container对于每个servlet declaration一定只对应一个实例。然而,当servlet实现了SingleThreadModel接口,container会创建多个实例来处理重量级的request访问,并且序列化request给某个实例。
在分布式环境下,container会为每一个JVM的每一个servlet declaration创建唯一实例。不过,如果在分布式应用中的servlet实现了SingleThreadModel接口,container会在一个JVM中创建一个servlet的多个实例。
SRV.2.2.1 Note About The Single Thread Model
SingleThreadModel接口保证了在同一时间内只有一个县城会执行给定servlet实例的service方法。需要特别注意的是这个保证值作用于每一个servlet实例,因为container可以选择将对象保存在池中,这些对象在同一时间内可以访问多个servlet实例,比如HttpSession的实例,可以在任何时间访问多个servlet,包括哪些实现了SingleThreadModel的servlet。
推荐开发者选择其他方式去解决这些问题而不是去实现这个接口,比如避免实例变量的使用或对存取资源的代码使用同步代码块。SingleThreadModel接口在这个版本的规范中是不被推荐使用的。
SRV.2.3 Servlet Life Cycle
Servlet通过完整生命周期定义被管理起来,这个生命周期定义了它如何被加载和创建、被初始化,如何处理来自client的请求,如何消亡。整个生命周期可以通过javax.servlet.Servlet接口API提供的方法init,service,destroy来表示,所有Servlet都必须直接或者间接通过GenerricServlet、HttpServlet抽象类来实现javax.servlet.Servlet。
SRV.2.3.1 Loading and Instantiation
Container负责装在和实例化servlet。装载和实例化的时机,有可能是在container启动时,或者直到container确定有request需要这个servlet的服务的时候。
当servlet引擎启动后,必要的servlet类一定会被servlet container加载。Servlet容器使用普通的java类加载设备加载servlet。加载可以来自本地文件系统,远程文件系统,或者其他网络服务。
在载入Servlet类之后,container会实例化servlet以备使用。
SRV2.3.2 Initialization
在servlet对象被实例化以后,container必须在它处理来自client的request之前做好它的初始化工作。在初始化时,servlet可以读取持久化配置数据,初始化昂贵的(costly)资源(比如基于JDBC的connection),并且执行其他一次性的动作。Container初始化servlet实例,通过调用Servlet接口的init方法,这个方法以唯一的(每个servlet声明一个)ServletConfig对象为参数。这个配置对象允许servlet从web application的配置中读取name-value的初始化参数信息。此配置对象使得servlet可以访问描述了servlet runtime environment的对象(实现了ServletContext接口的)。参见SRV.3 Servlet Context获得更多关于ServletContext的信息。
SRV.2.3.2.1 Error Conditions on Initialization
在初始化的过程中,servlet实例有可能抛出UnavailableException或者ServletException。在这种情况下,servlet一定不会被置为有效的服务,并且一定会被container释放掉。在container认为初始化工作不成功的情况下,destroy方法不会被调用。
在初始化失败后,container可以创建一个新的实例并且对它进行初始化。异常抛出的规则是:当UnavailableException抛出的次数达到不可用次数的下限,并且container处在等待创建并初始化一个新servlet实例的时刻。
SRV.2.3.2.2 Tool Considerations
当工具加载并且introspect web application时,静态初始化方法的触发不同于init方法的调用。开发者应该知道servlet在init方法被调用之前是不会处于有效的container runtime中的。比如:当只有静态初始化方法被调用时,servlet不应试图建立数据库连接或者EJB container。
SRV.2.3.3 Request Handling
在servlet被正确地初始化后,container就可以使用它来处理客户端request了。ServletRequest类型的对象用来表示request,ServletResponse类型的对象用来表示response。它们作为参数传递给Servlet接口的service方法。
在HTTP request的情况下,container提供的对象的类型为HttpServletRequest和HttpServletResponse。
需要注意的是,被servlet container放置到服务中的servlet实例有可能在他的生命周期里一个request都没处理。
SRV.2.3.3.1 Multithreading Issues
Container可以向servlet的service方法发送并发的request,为了处理这些request,servlet开发者必须为service方法中的多线程并发处理做好充分的准备。
尽管不是推荐的,但对于开发者来说,通过实现SingleThreadModel接口来要求container保证统一时刻内只有一个reqeust线程作用于service方法,仍然是一种选择。Servlet container可以满足这种要求,通过序列化访问servlet的request,或者通过维护一个servlet实例的对象池来实现。如果web应用程序已经被标记为分布式的,而servlet又是web应用程序的一部分,那么container可以在每一个JVM(JVM that the application is distributed across)上维护一个servlet的对象池。
对于那些没有实现SingleThreadModel接口的,如果service方法(或doGet, doPost之类那些被dispatch到HttpServlet抽象类的service方法的方法)已经使用synchronized关键字定义,container就无法使用对象池的方法,但是一定会序列化request传入service。在这种情况下,强烈建议开发者不要synchronize service方法(或dispatch到它的方法),因为这对性能有不利的影响。
SRV.2.3.3.2 Exception During Request Handling
在处理request的过程中,Servlet有可能会抛出ServletException或者UnavailableException。
ServletException被抛出说明在处理request的过程中出现了一些错误,并且container应该采取适当的措施来清理request。
UnavailableException意味着servlet暂时或者永久性的无法处理request。
如果UnavailableException指出的是永久性不可用,container就会把servlet从service中移除,调用它的destroy方法并且释放这个servlet实例。由于这个原因导致被container拒绝的任何request,都会返回一个SC_NOT_FOUND(404) response。
如果UnavailableException指出的是暂时性的不可用,container会选择在这个暂时无效的时期内不给servlet发送任何request。由于这个原因导致被container拒绝的任何request,都会返回一个SC_SERVICE_UNAVAILABLE(503) response,并附带一个在无效时间结束后重试的指示标题。
Container有可能会选择忽略暂时性无效和永久性无效的区别,并且对待所有UnavailableException作为永久性无效,因此remove servlet并且抛出UnavailableException。
SRV.2.3.3.3 Thread Safety
Request和Response对象的实现并不被保证是线程安全的。这意味着它们只应该在request处理线程内被使用(This means that they should only be used within the scope of the request handling thread)。
Request对象和Response对象的引用不应该交给那些在其他线程里运行的对象,因为resulting behavior有可能是非确定的。如果应用程序创建的线程使用了container管理的对象,比如request对象或者response对象,那些必须只能在servlet的service方法生命周期中使用的对象,并且这样的线程本身的生命周期存在于serlvet的service方法之内,因为在service方法结束之后访问这些对象有可能导致某些不确定的问题。请注意request对象和response对象是非线程安全的。如果那些对象被使用在多线程中,操作应当被同步或者通过包装再使用来达到线程安全。例如,同步存取request attribute的方法的调用,或者在一个线程中给response使用本地输出流。
SRV.2.3.4 End of Service
Servlet container并不用在任何特定的时间段保持一个servlet处于被加载的状态。在container中,一个servlet实例的生命周期 有可能只有几毫秒,也可能 和container的生命周期一样长,或者在这之间的某个时间段。
当container确定一个servlet应该从service中被remove掉,它就会调用Servlet接口的destroy方法来使servlet释放它用到的任何资源,并保存所有持久化状态。比如,当container想要保存内存资源,或者被停掉的时候,container就可以这么做。
在servlet container 调用destroy方法之前,它必须使这个servlet的service方法中所有当前在运行的线程都执行完毕,或在在server限定的时间内提前完成。
一旦servlet实例的destroy方法被调用,container就不会再把其他的request转交给servlet实例了。如果container需要再次使用这个servlet,它必须重新new一个此servlet的实例。
在destroy方法执行完毕后,container一定会释放这个servlet实例,以使垃圾回收能够顺利执行。
分享到:
相关推荐
Python双语言混合开发 中go语言版 mxshop_goods-srv.sql
1.4 Servlet 与其他技术的比较 ........................................................................................................................14 1.5 与 Java 平台企业版的关系 ......................
首先很高兴VSuite.Ramdisk.Srv.Setup.4.6.7531.1240总算win 64位系统上实现永久使用了,虽然离完美破解还是很遥远,但是值得庆贺,特此说明: 1、64位系统较32位难破解原因主要在于数字签名上,由于rxvstor.sys是...
标题中的“srv蓝屏解决补丁”指的是针对服务器运行过程中出现的蓝屏问题,特别是由于srv.sys驱动程序导致的问题,而提供的一种修复解决方案。在Windows操作系统中,srv.sys是服务子系统的主要驱动程序,它负责处理...
Primo Ramdisk(VSuite Ramdisk II) 内存虚拟硬盘软件 使用内存模拟出超快速的硬盘,突破系统IO瓶颈,飞速提升计算机性能 Primo Ramdisk软件的主要功能是通过独特的软件算法将物理内存模拟成一个超快速的硬盘,在这个...
安装Primo Ramdisk Srv Mui 5.6.0的过程相对简单,用户只需运行"Primo.Ramdisk.Srv.Mui.Setup.5.6.0.exe"这个安装文件,按照向导指示操作即可。值得注意的是,为了激活软件,可能需要使用到"PrDSrv56crk.reg"这个...
PrimoCache 是一款可以将物理内存、SSD 硬盘或闪存盘等虚拟成硬盘缓存的软件,它可以自动将硬盘中读取的数据存入物理内存等速度较快的设备,当系统再次需要该数据时它可以很快从缓存设备中读取,而无需再次访问速度...
VSuite.Ramdisk.Srv.Setup.zip VSuite+Ramdisk+.Crack.By.XLTH.rar 包含配置文件
VSuite.Ramdisk.Srv.Setup.4.6.7531.1240是一款专为服务器设计的内存虚拟硬盘软件,它充分利用了服务器内存的高速性来创建临时的虚拟硬盘,以此提升数据的读写速度并减轻对物理硬盘的磨损。这款工具的核心理念在于将...
VSuite.Ramdisk.Srv.Setup.4.6.7531.1240是一款专为Windows 64位操作系统设计的内存虚拟磁盘软件。该版本为永久试用的XX版,允许用户在一定时间内无限制地体验其功能。Ramdisk技术是一种将计算机的RAM(随机存取内存...
嘿嘿。ipc入侵里开telnet需要用的srv 个人收集来的。。奉上
标题中的“srv.cpp.tar.gz_Server”表明这是一个与服务器端编程相关的项目,主要涉及C++语言,因为源代码文件“srv.cpp”通常代表C++程序。这个压缩包包含了一个名为“srv.cpp”的文件,我们可以推断这可能是服务器...
标题中的“srv.rar_srv”可能是指一个压缩包文件,其中包含了一个名为“srv”的服务器端程序。这个程序基于socket编程,用于实现简单的通信服务。在IT领域,socket编程是网络编程的基础,它允许两个或多个应用程序...
History_07_Srv.txt
【标题】"srv.rar_聊天工具" 涉及的核心知识点是聊天工具的服务器端开发,其中使用了winsock编程技术。Winsock是Windows操作系统中的一个API,它为应用程序提供了网络通信的能力,使得开发者能够创建基于TCP/IP协议...
《srv.rar_srv_服务端 DELPHI_服务端集合》是一个综合性的资源包,主要针对的是使用DELPHI开发服务端应用的初学者。这个压缩包包含了一系列与srv服务端相关的材料,旨在帮助用户理解srv服务端的工作原理,并提供...
SAS9.4,sid码更新日期到2020年5月30日。 sas工具9.4版本,的sid更新代码,直接把begin里的内容做替换 或者直接使用renewsas进行更新
《PrimoCache v3.09:提升硬盘性能的秘密武器》 在当今的计算机领域,存储设备的速度对系统整体性能有着显著的影响。尤其对于那些依赖大量数据读取的应用程序,如游戏、视频编辑软件和数据库服务,硬盘的读取速度至...
tac_plus_srv.zip服务器源码。ubuntu下解压安装,方法都在对应的文档中