Servlet:服务器的左膀右臂

tech2022-07-04  225

Servlet 介绍

Servlet 是运行在 Java 服务器端的程序,用于接收和响应来自客户端基于 HTTP 协议的请求。如果想实现 Servlet 的功能,可以通过实现 javax.servlet.Servlet 接口或者继承它的实现类。 核心方法:service(),任何客户端的请求都会经过该方法。

Servlet 执行过程

Servlet 关系视图

Servlet 实现方式

1. 第一种 实现 Servlet 接口,实现所有的抽象方法。该方式支持最大程度的自定义。 2. 第二种 继承 GenericServlet 抽象类,必须重写 service 方法,其他方法可选择重写。该方式让我们开发 Servlet 变得简单。但是这种方式和 HTTP 协议无关。 3. 第三种 继承 HttpServlet 抽象类,需要重写 doGet 和 doPost 方法。该方式表示请求和响应都需要和 HTTP 协议相关。

Servlet 生命周期

对象的生命周期,就是对象从出生到死亡的过程。即:出生>> 活着 >> 死亡。官方说法是对象创建到销毁的过程!

1 出生:请求第一次到达 Servlet 时,对象就创建出来,并且初始化成功。只出生一次,将对象放到内存中。

2 活着:服务器提供服务的整个过程中,该对象一直存在,每次都是执行 service 方法。

3 死亡:当服务停止时,或者服务器宕机时,对象死亡。

结论:Servlet 对象只会创建一次,销毁一次。所以 Servlet 对象只有一个实例。如果一个对象实例在应用中是唯一的存在,那么我们就称它为单例模式。

详细过程: 客户端请求该 Servlet; 加载 Servlet 类到内存; 实例化并调用init()方法初始化该 Servlet; service()(根据请求方法不同调用doGet() 或者 doPost(),此外还有doHead()、doPut()、doTrace()、doDelete()、doOptions()、destroy())。 加载和实例化 Servlet。这项操作一般是动态执行的。然而,Server 通常会提供一个管理的选项,用于在 Server 启动时强制装载和初始化特定的 Servlet。 Server 创建一个 Servlet的实例 第一个客户端的请求到达 Server Server 调用 Servlet 的 init() 方法(可配置为 Server 创建 Servlet 实例时调用,在 web.xml 中 标签下配置 标签,配置的值为整型,值越小 Servlet 的启动优先级越高) 一个客户端的请求到达 Server Server 创建一个请求对象,处理客户端请求 Server 创建一个响应对象,响应客户端请求 Server 激活 Servlet 的 service() 方法,传递请求和响应对象作为参数 service() 方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息 service() 方法使用响应对象的方法,将响应传回Server,最终到达客户端。service()方法可能激活其它方法以处理请求,如 doGet() 或 doPost() 或程序员自己开发的新的方法。 对于更多的客户端请求,Server 创建新的请求和响应对象,仍然激活此 Servlet 的 service() 方法,将这两个对象作为参数传递给它。如此重复以上的循环,但无需再次调用 init() 方法。一般 Servlet 只初始化一次(只有一个对象),当 Server 不再需要 Servlet 时(一般当 Server 关闭时),Server 调用 Servlet 的 destroy() 方法。

Servlet 线程安全问题

由于 Servlet 采用的是单例模式,也就是整个应用中只有一个实例对象。所以我们需要分析这个唯一的实例对象中的类成员是否线程安全。根据用户登录功能来查看 Servlet 线程是否安全结论:一个浏览器代表一个线程,多个浏览器代表多个线程。按理说我们期望的应该是每个浏览器查看的都应该是自己的用户名。而现在的结果是浏览器中数据混乱。因此,我们可以认为 Servlet 是线程不安全的!解决:定义类成员要谨慎。如果是共用的,并且只会在初始化时赋值,其他时间都是获取的话,那么是没问题的。如果不是共用的,或者每次使用都有可能对其赋值,那就要考虑线程安全问题了,可以将其定义到 doGet 或 doPost 方法内或者使用同步功能即可。

Servlet 映射方式

1. 第一种 具体名称的方式。访问的资源路径必须和映射配置完全相同。 2. 第二种 / 开头 + 通配符的方式。只要符合目录结构即可,不用考虑结尾是什么。 3. 第三种 通配符 + 固定格式结尾的方式。只要符合固定结尾格式即可,不用考虑前面的路径。

注意:优先级问题。越是具体的优先级越高,越是模糊通用的优先级越低。第一种 >>第二种 >> 第三种。

Servlet 创建时机

1. 第一次访问时创建 优势:减少对服务器内存的浪费。提高了服务器启动的效率。 弊端:如果有一些要在应用加载时就做的初始化操作,无法完成。 2. 服务器加载时创建 优势:提前创建好对象提高了首次执行的效率,可以完成一些应用加载时要做的初始化操作。 弊端:对服务器内存占用较多,影响了服务器启动的效率。 修改 Servlet 创建时机。在servlet标签中,添加load-on-startup标签 正整数代表服务器加载时创建,值越小、优先级越高。 负整数或不写代表第一次访问时创建。

ServletConfig

ServletConfig 是 Servlet 的配置参数对象,在 Servlet 的规范中,允许为每一个 Servlet 都提供一些初始化的配置。所以,每个 Servlet 都有一个自己的 ServletConfig。

作用:在 Servlet 的初始化时,把一些配置信息传递给 Servlet。 生命周期:和 Servlet 相同。 ServletConfig 配置方式 在标签中,通过标签来配置。有两个子标签。 param-name:代表初始化参数的 key。 param-value:代表初始化参数的 value。 ServletConfig 常用方法 ServletConfig 实现步骤

定义一个类,继承 HttpServlet。在成员位置,声明一个 ServletConfig 对象。重写 init 方法,并为 ServletConfig 对象赋值。重写 doGet 和 doPost 方法。在 web.xml 文件中进行配置。在 doGet 方法中获取初始化参数。部署并启动项目。通过浏览器测试。

ServletContext

ServletContext 介绍 ServletContext 是应用上下文对象。每一个应用中只有一个 ServletContext 对象。 作用:可以获得应用的全局初始化参数和达到 Servlet 之间的数据共享。 生命周期:应用一加载则创建,应用被停止则销毁。 ServletContext的域对象

域对象指的是对象有作用域。也就是有作用范围。域对象可以实现数据的共享。不同作用范围的域对象,共享数据的能力也不一样。

在 Servlet 规范中,一共有 4 个域对象。ServletContext 就是其中的一个。它也是 web 应用中最大的作用域,也叫 application 域。它可以实现整个应用之间的数据共享!

ServletContext 配置方式 ServletContext 并不属于某个 Servlet 的配置,而是针对于整个应用的配置,也叫全局的初始化参数。 在web-app标签中,通过context-param标签来配置。有两个子标签。 param-name:代表全局初始化参数的 key。 param-value:代表全局初始化参数的 value。 ServletContext 常用方法 ServletContext 实现步骤

定义一个类,继承 HttpServlet。重写 doGet 和 doPost 方法。在 web.xml 文件中配置 Servlet 和 ServletContext。获取 ServletContext 对象。测试相关方法的使用。部署并启动项目。通过浏览器测试。

注解开发 Servlet

普通开发与注解开发对比 自动注解开发的实现步骤

创建一个 web 项目。定义一个类,继承 HttpServlet。重写 doGet 和 doPost 方法。在类上使用 @WebServlet 注解配置 Servlet。部署并启动项目。通过浏览器测试。

自动注解开发的注解详解

最新回复(0)