Servlet:服务器的左膀右臂

本文全面解析Servlet的工作原理,包括其实现方式、生命周期、线程安全问题及解决方案,同时介绍了Servlet的映射方式、创建时机和配置参数,以及如何利用注解进行开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 线程安全问题

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

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

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 实现步骤

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

注解开发 Servlet

普通开发与注解开发对比
在这里插入图片描述
自动注解开发的实现步骤

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

自动注解开发的注解详解
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值