Servlet

一、Servlet是什么

      宏观地讲,Servlet是连接web服务器和服务端Java程序的协议,是一种通信规范,以一套接口的形式体现的。

      通常来说,Servlet是宏观上Servlet规范中的一个具体接口,Servlet规范中包含一套接口,Servlet接口是其中之一。(在Java中存在于javax.servlet包中)

      微观来讲,Servlet是Servlet接口实现类的一个实例对象,是运行在服务器上的一段Java小程序,即Server Applet。Servlet的主要功能是根据客户端提交的请求,调用服务端相关Java代码,完成对请求的处理和运算。

*Servlet接口中的方法

 

二、Servlet的注册

在创建了实现Servlet接口的类以后,Servlet在web.xml中注册。

1. Servlet实现类的注册

2. 建立映射关系

其中,一个Servlet可以有多个urlPattern与之匹配,

它的设置模式有以下几种:

(1)精确路径模式:如/here/some,请求路径和<url-pattern>的值完全相同才可被当前Servlet处理

(2)通配符路径模式:如/here/*,只要有/here/后面无论是什么都可被当前Servlet处理

(3)全路径模式:如/*,什么路径都可以匹配上,所有请求(包括所有动态资源和静态资源)通通拦截交给该Servlet处理;对于/,只能拦截静态资源,对于动态资源的请求(如jsp)不能被匹配上

(4)后缀名模式:如*.do,所有后缀名为do的请求都会被匹配上,一般是.do或者.action

它的匹配原则是:

(1)路径优先后缀匹配原则:同时匹配上路径和后缀名方式时,优先根据路径匹配Servlet

(2)精确路径优先匹配原则:同时匹配上几种路径时,优先以更精确(不带通配符)的路径匹配Servlet

(3)最长路优先匹配原则:同时匹配上几种带通配符/不带通配符的路径时,优先以更精切的路径匹配Servlet

 

三、Servlet的生命周期

      Servlet整个生命周期过程的执行,均由web服务器负责管理(Servlet接口中实现的方法也只能由服务器调用),程序员无法控制器其流程。但是程序员可以获取到Servlet的生命周期时间点,并可以指定让Servlet做一些具体业务有关的事情。

      当请求到达服务器,服务器会解析请求,解析出URI,解析出其中的ServletPath,并结合web.xml配置文件找到出对应的Servlet。

      之后,若不存在该Servlet,会通过反射机制调用构造器构造,之后初始化;如果已经存在,直接调用service()方法进行服务调用。也就是说,Servlet的创建和初始化是在第一次访问对应的url时,之后的每次访问只需要只需要直接调用service()方法。

      而且,Servlet是单例多线程的,在服务器中只有一个实例对象,可被多个浏览器访问。

      在容器被关闭时,或者该应用被关闭时,调用destroy()方法,Servlet实例被销毁。

 

四、Servlet的特征

     

 

五、在web容器启动时就创建Servlet

       由于Servlet的创建和初始化是在第一次访问对应的url时,所以对于第一个访问该url的用户来说,他等待的时间稍微长一点。为了提升用户体验,可以将一些常用Servlet在web容器启动时就创建。<load-on-startup>属性会让Servlet在容器启动时就被创建且被初始化。

其中<load-on-startup>之间必须是≥0的整数,其值代表了创建时的优先级。0的优先级最大。

 

六、创建Servlet的过程

 

1. 请求到达服务端,在第一个map中通过请求的url找到对应的Servlet引用,如果存在,调用该Servlet的service()方法;

2. 如果不存在,到第二个map中通过请求的url找到对应的Servlet全限定类名,通过反射机制(class.forName())创建一个该Servlet类的实例并且初始化;说明此时该Servlet还未创建,这是服务器启动后该URL第一次被访问

3. 把(url,新建的实例引用)放入第一个map中,并且调用该Servlet的service()方法;

 

七、ServletConfig

1. 什么是ServletConfig

      可以从Servlet规范接口的init()方法中看到,服务器调用init方法时,会传入一个ServletConfig接口类型的参数。实际上,这个参数里面包含了Servlet的一些信息。但是我们不知道这个ServletConfig接口的实现类是谁,这就是协议的面向接口的抽象编程。

实际上,顾名思义,一个ServletConfig对象就对应了xml文件中注册的一个Servlet对象,它包含了这个Servlet对象的一些信息。

ServletConfig接口所包含的方法有如下几个:

(1)getInitParameter(String Name):获取以“name”为参数名称的参数的值。

(2)getInitParameterNames():返回一个String的枚举,是所有参数名字的枚举。

(3)getServletContext():获取Servlet上下文。

(4)getServletName():获取Servlet的名称。

 

2. 获取ServletConfig对象

可以发现Servlet另外提供了一个方法获取这个ServletConfig参数。

 

3. 通过ServletConfig获取Servlet的相关信息

 获取到这个对象后,我们可以通过调用ServletConfig的一些方法来获取想得到的信息。

 

示例:

 

 

4. ServletContext的使用

通过ServletConfig可以获取一个名为ServletContext的属性。实际上,ServletContext中可以定义域属性和初始化参数,是与servlet对象无关的,是全局性的,可以在任意一个servlet中获取。

(1)初始化参数相关:getInitParameterNames()和getInitParameter(String Name)

在web.xml文件中,定义上下文初始化参数:

在代码中,可通过ServletContext获取:

启动服务器,在网页上访问该servlet对应的url,控制台输出:

(2)域属性相关:setAttribute(String Name, Object object)和removeAttribute(String Name)

在AServlet对象中设置域属性:

在BServlet中获取域属性:

启动服务器,在网页上访问BServlet对应的url,控制台输出:

之后,在BServlet中修改域属性:

启动服务器,在网页上访问BServlet对应的url,控制台输出:

(3)路径有关:getContextPath()和getRealPath(String path)

在控制台同样发现:

发现getContextPath()获取到的就是应用名称,而getRealPath(String path)是将URI转变为基于本地文件系统(file协议)下的文件路径。

 

七、只关注Servlet接口的service()方法

1.  GenericServlet抽象类(缺省适配器设计模式)

如下所示:抽象类GenericServlet,包含了抽象方法service(),其余四个方法空实现。

在这之后,再想要定义Servlet相关类的时候,只需继承GenericServlet类,并且只需实现其中的service()方法即可。

也可以将比较上层的工作留在GenericServlet类中完成,比如ServletConfig的获取:

(1)GenericServlet类除了实现Servlet接口以外,还实现ServletConfig接口;

(2)在GenericServlet类中定义private ServletConfig sc,并且在init()和getServletConfig()中赋值给sc;

(3)实现ServletConfig接口的四个方法;

这样一来,在GenericServlet的子类中,只需要调用父类GenericServlet的这四个方法就可以获取ServletConfig里的相关信息,无需接触sc。

而在Servlet规范中,已经实现了GenericServlet类。

 

 

 

 

 

 

 

 

 

posted @ 2019-04-17 10:46  kiki's  阅读(285)  评论(0编辑  收藏  举报