Servlet 编程
Servlet 编程基础
Servlet 是连接 Web 服务器与服务端 Java 程序的协议,是一种通信规范。这个规范是以一套接口的形式体现的。
Servlet 规范中包含一套接口。而 Servlet 接口仅仅是其中之一。
微观地讲,Servlet 是 Servlet 接口实现类的一个实例对象,是运行在服务器上的一段 Java小程序,即 Server Applet,也就是 Servlet 这个单词的来历。Servlet 的主要功能是根据客户端提交的请求,调用服务器端相关 Java 代码,完成对请求的处理与运算。
1.1、Servlet生命周期
Servlt 生命周期是指,Servlet 对象的创建、Servlet 对象的初始化、Servlet 对象服务的执行,及最终 Servlet 对象被销毁的整个过程。
Servlet 的整个生命周期过程的执行,均由 Web 服务器负责管理。即 Servlet 从创建到服务到销毁的整个过程中方法的调用,都是由 Web 服务器负责调用执行,程序员无法控制其执行流程。
但程序员可以获取到 Servlet 的这些生命周期时间点,并可以指定让 Servlet 做一些具体业务相关的事情。
1.1.1、 生命周期方法执行流程
Servlet 生命周期方法的执行流程:
当请求发送到 Web 容器后,Web 容器会解析请求 URL,并从中分离出 Servlet 对应的URI。
根据分离出的 URI,通过 web.xml 中配置的 URI 与 Servlet 的映射关系,找到要执行的Servlet,即找到用于处理该请求的 Servlet。
若该 Servlet 不存在,则调用该 Servlet 的无参构造器、init()方法,实例化该 Servlet。然后执行 service()方法。
若该 Servlet 已经被创建,则直接调用 service()方法。
当 Web 容器被关闭,或该应用被关闭,则调用执行 destroy()方法,销毁 Servlet 实例。
1 |
|
1.1.2、Servlet特征
Servlet 是单例多线程的。
一个 Servlet 实例只会执行一次无参构造器与 init()方法,并且是在第一次访问时执行。
用户每提交一次对当前 Servlet 的请求,就会执行一次 service()方法。
一个 Servlet 实例只会执行一次 destroy()方法,在应用停止时执行。
由于 Servlet 是单例多线程的,所以为了保证其线程安全性,一般情况下是不为 Servlet类定义可修改的成员变量的。因为每个线程均可修改这个成员变量,会出现线程安全问题。
默认情况下,Servlet 在 Web 容器启动时是不会被实例化的。
1.1.3、Web 容器启动时创建 Servlet 实例
在默认的情况下,Servlet在Web容器启动时不会被实例化
修改配置文件:
1 |
|
在
它的值必须是一个整数。
当值大于等于 0 时,表示容器在启动时就加载并初始化这个 Servlet,数值越小,该 Servlet的优先级就越高,其被创建的也就越早;
当值小于 0 或者没有指定时,则表示该 Servlet 在真正被使用时才会去创建。
当值相同时,容器会自己选择创建顺序。
1.1.4、getServletInfo()方法
Servlet 接口中的方法 getServletInfo(),是由程序没自己定义的有关当前 Servlet 的一些基本信息,不属于 Servlet 生命周期中的方法。
1.2、SerlvetConfig
1.2.1、什么是ServletConfig
在 Servlet 接口的 init()方法中具有唯一的一个参数 ServletConfig。
ServletConfig 是个接口,顾名思义,就是 Servlet 配置,即在 web.xml 中对当前 Servlet 类的配置信息。Servlet 规范将Servlet 的配置信息全部封装到了 ServletConfig 接口对象中。
在 Web 容器调用 init()方法时,Web 容器首先会将 web.xml 中当前 Servlet 类的配置信息封装为一个对象。这个对象的类型实现了 ServletConfig 接口,Web 容器会将这个对象传递给init()方法中的 ServletConfig 参数。
1.2.2、获取ServletConfig
由于 ServletConfig 对象是 Web 容器通过 init()方法传递给当前 Servlet 类的,而 init()方法只会在 Servlet 对象初始化时调用一次。所以,需要在 init()方法中将 ServletConfig 对象传递给 Servlet 的 ServletConfig 成员变量,这样 service()方法即可使用 ServletConfig 对象了。也就是说,我们需要在 Servlet 中声明一个ServletConfig 成员变量。
声明了成员变量之后,会不会存在线程安全问题?
ServletConfig变量的赋值是在init()方法进行赋值,对于所有线程来说,SerlvetConfig对象是可读的,但不能修改。
1.2.3、ServletConfig 中的方法
在Java帮助文档中,可以看到接口的四个方法:
1 |
|
getInitParameter()
:获取指定名称的初始化参数值。1
getInitParameter("myName")
getInitParameterNames()
:获取当前 Servlet 所有的初始化参数名称。其返回值为枚举类型 Enumeration。 1
getInitParameterNames()
getServletName()
:获取当前 Servlet 的中指定的 Servlet 名称。如上图中的 ServletName 为”hello-servlet”。 1
getServletName()
getServletContext()
:获取到当前 Servlet 的上下文对象 ServletContext。这是个非常重要的对象。1
getServletContext()
1.2.4、ServletConfig的特点
对于不同的Servlet,Tomcat会为其创建不同的ServletConfig,用于封装各自的配置信息。也就是说,一个 Servlet 就会有其对应的一个 ServletConfig 对象。
1.3、ServletContext
1.3.1、什么是ServletContext
ServletContext,即 Servlet 上下文环境,是个接口,是 Web 应用中所有 Servlet 在 Web 容器中的运行时环境。
这个运行时环境随着 Web 应用的启动而创建,随着 Web 应用的关闭而销毁。也就是说,一个 Web 应用,就一个 Servlet 运行时环境,即一个ServletContext 对象。
ServletContext运行环境中有哪些具体的内容?
web.xml 文件中的配置信息
Servlet之间 可以共享的数据
可以这么说,ServeltContext 可以代表整个Web应用。所以,ServletConetxt有另外一个名称:application
。
1.3.2、ServletContext中的方法
查看 Java的帮助文档,可以看到 javax.servlet.ServletContext
接口中包含很多方法。
下面我们介绍几个常用的重要方法。
在 web.xml 中通过
上下文参数
与初始化参数 是不同的: 上下文参数是当前 Web 应用中所有 Servlet 共享的参数,每个 Servlet 均可获取到.
Servlet 初始化参数则是只有当前Servlet 可以获取到的参数。
1 |
|
方法:
String getInitParameter ()
获 取 web.xml 文 件 的
中 指 定 名 称 的 上 下 文 参 数 值 。 Enumeration getInitParameterNames()
获取 web.xml 文件的
中的所有的上下文参数名称。 void setAttribute(String name, Object object)
1
setAttribute("User",new User());
在 ServletContext 的公共数据空间中,也称为域属性空间,放入数据。
这些数据对于 Web应用来说,是全局性的,与整个应用的生命周期相同。
Object getAttribute(String name)
1
User user = (User)getAttribute("User");
从 ServletContext 的域属性空间中获取指定名称的数据。
void removeAttribute(String name)
1
removeAttribute("User")
从 ServletContext 的域属性空间中删除指定名称的数据。
String getRealPath(String path)
获取当前 Web 应用中指定文件或目录在本地文件系统中的路径,是基于盘符的路径。绝对路径。
String getContextPath()
获取当前应用在 Web 容器中的名称。
1.4、欢迎页面设置
1.4.1、欢迎页面设置
欢迎页面,是指当在浏览器地址栏中直接通过项目名称访问时,默认显示的页面,即默认访问的路径,可以是个.html、.jsp 等页面,也可以是 Servlet 的访问路径等。
1 |
|
在 web.xml 中有一个
1.4.2、指定多个欢迎页面
1 |
|
可以为应用指定多个欢迎页面,但只会有一个起作用。系统加载这些欢迎页面的顺序与其注册顺序相同,即由上到下逐个查找。一旦找到,则马上显示,不会再向下查找
1.5、 的设置与匹配
对于
1.5.1、精确路径模式
请求路径必须与
1 |
|
1.5.2、通配符路径模式
该模式中的路径由两部分组成:精确路径部分与通配符部分。
请求路径中只有携带了
1 |
|
1.5.3、全路径模式
提交的所有请求全部可被当前的 Servlet 处理。其值可以指定为/*,也可指定为/。
1 |
|
/*与/表示所有请求均会被当前 Servlet 所处理。这两个路径的不同之处是:
- 使用/*,表示当前的 Servlet 会拦截用户对于静态资源(.css、.js、.html、.jpg、.png…..)与动态资源(.jsp)的请求。即用户不会直接获取到这些资源文件,而是将请求交给当前 Servlet
来处理了。
- 使用/,表示当前的 Servlet 会拦截用户对于静态资源(.css、.js、.html、.jpg、.png…..),但对于动态资源的请求,是不进行拦截的。即用户请求的静态资源文件是不能直接获取到的。
1.5.4、后缀名模式
请求路径最后的资源名称必须携带
1 |
|