Servlet
什么是Servlet?
-
第一:Servlet是一个运行在web服务端的java小程序
-
第二:它可以用于接收和响应客户端的请求
-
第三:要想实现Servlet功能,可以实现Servlet接口,继承GenericServlet或者HttpServlet
-
第四:每次请求都会执行service方法
-
第五:Servlet还支持配置
-
具体请看下图:
Servlet执行流程?
-
我们通过浏览器发送请求,请求首先到达Tomcat服务器
-
由服务器解析请求URL,然后在部署的应用列表中找到我们的应用
-
接下来,在我们的应用中找应用里的web.xml配置文件
-
在web.xml中找到Servlet的配置
-
找到后执行service方法,最后由ServletDemo1响应客户浏览器
一句话总结执行过程:
浏览器——>Tomcat服务器——>我们的应用——>应用中的web.xml——>Servlet——>响应浏览器
Servlet关系视图
-
Servlet,GenericServlet,HTTPServlet,他们都有service方法
-
service方法都有俩参数,ServletRequest,ServletResponse
-
HTTPServlet的参数是HttpServletRequest,HttpServletResponse,他们分别继承自ServletRequest,ServletResponse
-
这俩参数都是接口,分别处理请求,响应
-
ServletConfig,处理配置
-
ServletContext,处理多个Servlet之间信息共享
Servlet实现方式
-
第一种 实现 Servlet 接口,实现所有的抽象方法。该方式支持最大程度的自定义。
-
第二种 继承 GenericServlet 抽象类,必须重写 service 方法,其他方法可选择重写。该方式让我们开发 Servlet 变得简单。但是这种方式和 HTTP 协议无关。
-
第三种 继承 HttpServlet 抽象类,需要重写 doGet 和 doPost 方法。该方式表示请求和响应都需要和 HTTP 协议相关。
Servlet的生命周期
-
对象的生命周期,就是对象从出生到死亡的过程。即:出生 -> 活着 -> 死亡。官方说法是对象创建到销毁的过程
-
出生:请求第一次到达 Servlet 时,对象就创建出来,并且初始化成功。只出生(创建)一次,将对象放到内存中
-
活着:服务器提供服务的整个过程中,该对象一直存在,每次都是执行 service 方法
-
死亡:当服务停止时,或者服务器宕机时,对象死亡
-
结论:Servlet 对象只会创建一次,销毁一次。所以 Servlet 对象只有一个实例。如果一个对象实例在应用中是唯一的存在,那么我们就称它为单例模式
如何解决Servlet的线程安全问题?
定义类成员要谨慎。如果是共用的,并且只会在初始化时赋值,其他时间都是获取的话,那么是没问题的。如果不是共用的,或者每次使用都有可能对其赋值,那就要考虑线程安全问题了,可以将其定义到 doGet 或 doPost 方法内或者使用同步功能(加锁)即可。
不同的映射方式
-
第一种 具体名称的方式。访问的资源路径必须和映射配置完全相同
-
第二种 / 开头 + 通配符的方式。只要符合目录结构即可,不用考虑结尾是什么
-
第三种 通配符 + 固定格式结尾的方式。只要符合固定结尾格式即可,不用考虑前面的路径
注意:优先级问题。越是具体的优先级越高,越是模糊通用的优先级越低。第一种 -> 第二种 -> 第三种
Servlet创建时机的优劣分析
-
第一次访问时创建
优势:减少对服务器内存的浪费。提高了服务器启动的效率
弊端:如果有一些要在应用加载时就做的初始化操作,无法完成
-
服务器加载时创建
优势:提前创建好对象,提高了首次执行的效率。可以完成一些应用加载时要做的初始化操作
弊端:对服务器内存占用较多,影响了服务器启动的效率
-
修改 Servlet 创建时机。在
<servlet>
标签中,添加<load-on-startup>
标签。 -
正整数代表服务器加载时创建,值越小、优先级越高。 负整数或不写代表第一次访问时创建**
-
<load-on-startup>加载顺序的序号</load-on-startup>
-
序号为1,就是服务器启动时第一个加载
-
序号为2,就是服务器启动时第二个加载
-
-
如果两个Servlet都要配置为正整数,那么值小的优先级高
-
配置:修改ServletDemo3的配置,增加load-on-startup
ServletConfig
什么是ServletConfig,作用是什么?
-
ServletConfig 是 Servlet 的配置参数对象,在 Servlet 的规范中,允许为每一个 Servlet 都提供一些初始化的配置。所以,每个 Servlet 都有一个自己的 ServletConfig
-
作用:在 Servlet 的初始化时,把一些配置信息传递给 Servlet
ServletConfig生命周期
-
生命周期:和 Servlet 相同
-
由于它是在初始化阶段读取了web.xml中为Servlet准备的初始化配置,并把配置信息传递给Servlet,所以生命周期与Servlet相同
-
这里需要注意的是,如果Servlet配置了
<load-on-startup>1</load-on-startup>
,那么ServletConfig也会在应用加载时创建 -
ServletConfig的配置信息都是键值对的形式
-
在
<servlet>
标签中,通过<init-param>
标签来配置。有两个子标签。 -
<param-name>
:代表初始化参数的 key。 -
<param-value>
:代表初始化参数的 value。 -
一个init-param配置一个信息,一个信息由name和value组成
-
ServletConfig常用方法
返回值 | 方法名 | 说明 |
---|---|---|
String | getParameter(String name) | 根据参数名称获取参数值 |
Enumeration | getInitParameterName() | 获取所有参数名称的枚举 |
String | getServletName() | 获取Servlet的名称 |
ServletContest | getServletContext() | 获取ServletContext对象 |
ServletContext
什么是ServletContext?
-
ServletContext 是应用上下文对象。每一个应用中只有一个 ServletContext 对象。
-
作用:可以获得应用的全局初始化参数和达到 Servlet 之间的数据共享。
-
上下文理解:环境,不同环境给我们带来的信息是不一样的。所以环境中有很多信息,数据,也就是环境是用于存储数据的。
ServletContext的生命周期?
应用一加载则创建,应用被停止则销毁。
-
出生——活着——死亡
-
出生: 应用一加载,该对象就被创建出来了。一个应用只有一个实例对象。(Servlet和ServletContext都是单例的)
-
活着:只要应用一直提供服务,该对象就一直存在。
-
死亡:应用被卸载(或者服务器挂了),该对象消亡。
什么是域对象?
-
域对象指的是对象有作用域。也就是有作用范围
-
域对象可以实现数据的共享
-
不同作用范围的域对象,共享数据的能力也不一样
-
在 Servlet 规范中,一共有 4 个域对象
-
ServletContext 就是其中的一个
-
它也是 web 应用中最大的作用域,也叫 application 域
-
在整个项目范围都可以使用 应用域共享的数据
-
-
它可以实现整个应用之内的数据共享
-
ServletContext是一个接口,程序运行起来之后打印ServletContext的实例对象,其实是一个ApplicationContextFacade对象
-
ApplicationContextFacade是ServletContext的实现类
-
-
ServletContext的配置方式?
-
ServletContext 并不属于某个 Servlet 的配置,而是针对于整个应用的配置,也叫全局的初始化参数
-
在
<web-app>
标签中,通过<context-param>
标签来配置。有两个子标签 -
<param-name>
:代表全局初始化参数的 key -
<param-value>
:代表全局初始化参数的 value
注意ServletContext的配置是在wep-app节点下,与servlet配置同级别
ServletContext常用方法
返回值 | 方法名 | 说明 |
---|---|---|
String | getInitParameter(String name) | 根据名称获取全局配置的参数 |
String | getContextPath() | 获取当前路径访问的虚拟路径 |
String | getRealPath(String path) | 根据虚拟路径获取绝对路径 |
void | setAttribute(String name,Object value) | 向应用域对象中存储数据 |
Object | getAttribute(String name) | 通过名称获取应用域对象中的数据 |
void | removeAttribute(String name) | 通过名称删除应用域中的数据 |