文档章节

Servlet Specification V2.4——SRV.2 The Servlet Interface

悟空太多啦
 悟空太多啦
发布于 2015/12/20 23:53
字数 2623
阅读 14
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

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实例,以使垃圾回收能够顺利执行。

© 著作权归作者所有

悟空太多啦

悟空太多啦

粉丝 20
博文 86
码字总数 72074
作品 1
南京
其他
私信 提问
spring mvc 访问静态文件的问题!请指教!

这是web—xml的配置 TalentCloud index.jsp default *.js default *.css default *.png default *.jpg default *.gif spring3mvc org.springframework.web.servlet.DispatcherServlet 1 spri......

Ales_小溪
2013/07/22
845
1
web 基础巩固——JSP基础

本文按照官网文档总结,但是有可能会理解错误,学习时尽量和其他网站进行对比,同时也欢迎指出错误,好让我及时改正 什么是JSP页面? JSP页面是一个文本文档,包含两种类型的文本:静态数据,...

SXJR
2018/11/26
0
0
servlet和filter的异同

以前总以为filter就是一种特殊servlet,所以他们在web.xml中配置因该是一样的,但是事实并非如此! 请看下文: 看Servelt规范: 引用 A filter is a reusable piece of code that can transf...

dengzhangtao
2010/12/06
1K
1
web.xml中load-on-startup的作用

如下一段配置,熟悉DWR的再熟悉不过了: dwr-invoker org.directwebremoting.servlet.DwrServlet debug true 1 dwr-invoker /dwr/* 我们注意到它里面包含了这段配置:1,那么这个配置有什么作...

长平狐
2012/11/28
85
0
NetBeans 6.8 M1 对 J2EE 6.0 的支持(英文)

You may know that the next iteration of the Java Enterprise Edition, i.e. Java EE 6, is nearing completion. Many key specifications, including Java Persistence 2.0, JavaServer F......

红薯
2009/08/18
651
1

没有更多内容

加载失败,请刷新页面

加载更多

如何更改iOS应用程序的名称?

我前几天用一个愚蠢的开发代码名称开始了一个iPhone项目,现在我想改变项目的名称,因为它已经接近完成了。 但是我不知道如何使用Xcode来做这件事,尝试在info.plist文件中更改应用程序的名称...

技术盛宴
23分钟前
2
0
关于win10tensorflow的配置(CPU+GPU)

主要内容 CPU篇 GPU篇 【前期准备与注意事项】 环境:window1064位+python36(37)+CUDA9.0+cuDNN7.6+tensorflow_gpu-1.12.0 软件:anaconda+pycharm 硬件:有nvidia显卡的笔记本或台式(非A...

放只虎归个山
31分钟前
1
0
C#中的多行字符串文字

有没有一种简单的方法可以在C#中创建多行字符串文字? 这是我现在所拥有的: string query = "SELECT foo, bar"+ " FROM table"+ " WHERE id = 42"; 我知道PHP有 <<<BLOCKBLOCK; C#是......

javail
39分钟前
3
0
微信支付之小微商户扫盲!支持信用卡,免营业执照!

微信支付商户申请面向线下小微商户开放,符合条件的微信支付服务商可为小微商户发起接入申请。无需营业执照。 小微商户日收款额度为5万元~30万元 。 信用卡支付日限额为1千;月限额1万。 结算...

吴伟祥
今天
4
0
大话SDWebImage(三)-- 图片下载层

四、图片下载层 SDWebImageDownloader是处理图片下载的类 4.1 图片下载步骤 首先介绍下dispatch_barrier,GCD中的dispatch_barrier目的是在并发队列实现串行的效果,创建下载任务SDWebImageD...

aron1992
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部