一:Servlet(掌握)
1.Servlet概述
Servlet规范是javaEE规范之一,通过官方API网址,在左上部分找到javax.servlet包,在左下部分找到Servlet,如下图显示:
通过api可以阅读到:
第一:Servlet是一个运行在web服务端的java小程序
第二:它可以用于接收和响应客户端的请求
第三:要想实现Servlet功能,可以实现Servlet接口,继承GenericServlet或者HttpServlet
第四:每次请求都会执行service方法
第五:Servlet还支持配置
2.Servlet执行过程分析

3.Servlet类视图
4. Servlet的编写方式
我们在实现Servlet功能时,可以选择以下三种方式:
第一种:实现Servlet接口
接口中的方法必须全部实现。使用此种方式,表示接口中的所有方法在需求方面都有重写的必要。此种方式支持最大程度的自定义。
第二种:继承GenericServlet
service方法必须重写,其他方可根据需求,选择性重写。使用此种方式,表示只在接收和响应客户端请求这方面有重写的需求,而其他方法可根据实际需求选择性重写,使我们的开发Servlet变得简单。但是,此种方式是和HTTP协议无关的。
第三种:继承HttpServlet(经常使用)
它是javax.servlet.http包下的一个抽象类,是GenericServlet的子类。如果我们选择继承HttpServlet时,只需要重写doGet和doPost方法,不要覆盖service方法。使用此种方式,表示我们的请求和响应需要和HTTP协议相关。也就是说,我们是通过HTTP协议来访问的。那么每次请求和响应都符合HTTP协议的规范。请求的方式就是HTTP协议所支持的方式(目前我们只知道GET和POST,而实际HTTP协议支持7种请求方式,GET POST PUT DELETE TRACE OPTIONS HEAD )。
5. Servlet的使用细节
5.1 Servlet的生命周期
出生:
请求第一次到达Servlet时,对象就创建出来,并且初始化成功。只出生一次,就放到内存中。
活着:
服务器提供服务的整个过程中,该对象一直存在,每次只是执行service方法。
死亡:
当服务停止时,或者服务器宕机时,对象消亡。
结论:在Servlet的生命周期中,Servlet对象只会创建一次,销毁一次。如果一个对象实例在应用中是唯一的
存在,那么我们就称它为单例模式。
5.2 Servlet的线程安全
- 由于Servlet采用的事单例模式,也就是整个应用中只有一个实例对象,当定义成员时,很容易使成员变量的值发生混乱,所以Servlet的是线程不安全的。
解决方法:
Servlet的声明,通过反射机制创建Servlet对象
<!--声明Servlet--><servlet><!--给Servlet起一个名字--><servlet-name>studentServlet</servlet-name><!--Servlet的全限定类名--><servlet-class>com.itheima.servlet.StudentServlet</servlet-class></servlet>
Servlet的映射(3种)
第一种
具体名称的方式。访问的资源路径必须和映射配置完全相同。<!--servlet映射--><servlet-mapping><servlet-name>studentServlet</servlet-name><url-pattern>/studentServlet</url-pattern></servlet-mapping>
第二种
/ 开头 + 通配符的方式。只要符合目录结构即可,不用考虑结尾是什么。<!--通配符*代表任意字符--><servlet-mapping><servlet-name>studentServlet</servlet-name><url-pattern>/studentServlet/*</url-pattern></servlet-mapping>
第三种
通配符 + 固定格式结尾的方式。只要符合固定结尾格式即可,不用考虑前面的路径。<servlet-mapping><servlet-name>stuServlet4</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
5.4 Servlet的创建时机(了解)
第一次访问时创建
优势:减少对服务器内存的浪费。提高了服务器启动的效率。
弊端:如果有一些要在应用加载时就做的初始化操作,无法完成。服务器加载时创建
优势:提前创建好对象,提高了首次执行的效率。可以完成一些应用加载时要做的初始化操作。
弊端:对服务器内存占用较多,影响了服务器启动的效率。
修改 Servlet 创建时机。在标签中,添加标签。
正整数代表服务器加载时创建,值越小、优先级越高。 负整数或不写代表第一次访问时创建。
5.5 默认Servlet(了解)
默认Servlet是由服务器提供的一个Servlet,它配置在Tomcat的conf目录下的web.xml中。如下图所示:
它的映射路径是<url-pattern>/<url-pattern>,我们在发送请求时,首先会在我们应用中的web.xml中查找映射配置,找到就执行,这块没有问题。但是当找不到对应的Servlet路径时,就去找默认Servlet,由默认Servlet处理。所以,一切都是Servlet。
二:ServletConfig(了解)
1. ServletConfig概述
- ServletConfig 是 Servlet 的配置参数对象,在 Servlet 的规范中,允许为每一个 Servlet 都提供一些初始化的配置。所以,每个 Servlet 都有一个自己的 ServletConfig。
- 作用:在 Servlet 的初始化时,把一些配置信息传递给 Servlet。
- 生命周期:和 Servlet 相同。
2. ServletConfig的使用
- 在
标签中,通过 标签来配置。有两个子标签。类似于键值对形式。 :代表初始化参数的 key。 :代表初始化参数的 value。 <!--ServletConfig配置--><servlet><servlet-name>ServletConfig</servlet-name><servlet-class>com.itheima.servlet.ServletConfigDemo1</servlet-class><!--配置ServletConfig--><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>desc</param-name><param-value>this is a config</param-value></init-param></servlet>
三:ServletContext(掌握)
1. ServletContext介绍
ServletContext 是应用上下文对象(应用域对象)。每一个应用中只有一个 ServletContext 对象。
- 作用:可以获得应用的全局初始化参数和达到 Servlet 之间的数据共享。
- 生命周期:应用一加载则创建,应用被停止则销毁。

ps:可以把ServletContext对象看成一个全局仓库,不同的Servlet对象可以在这个仓库中存东西,拿东西,即Servlet对象共享这个仓库。
2. 域对象概念
- 域对象指的是对象有作用域。也就是有作用范围。域对象可以实现数据的共享。不同作用范围的域对象,共享数据的能力也不一样。
在 Servlet 规范中,一共有 4 个域对象。ServletContext 就是其中的一个。它也是 web 应用中最大的作用域,也叫 application 域。它可以实现整个应用之间的数据共享!
3. 如何获取ServletContext对象
方法一:通过调用ServletConfig对象的getServletContext()方法。
public class ServletDemo9 extends HttpServlet {//定义Servlet配置对象ServletConfigprivate ServletConfig servletConfig;//在初始化时为ServletConfig赋值@Overridepublic void init(ServletConfig config) throws ServletException {this.servletConfig = config;}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.获取ServletContext对象ServletContext servletContext = servletConfig.getServletContext();System.out.println(servletContext);}}
方法二:在GenericServlet类中,已经为我们声明了ServletContext获取的方法,如下图:

因为我们的类继承HttpServlet,而HttpServlet又是GenericServlet的子类,所以我们在获取ServletContext时,如果当前Servlet没有用到它自己的初始化参数时,就可以不用再定义初始化参数了,而是直接调用父类的getServletContext()方法就行了 。@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext servletContext = super.getServletContext();}
4. ServletContext配置方式
ServletContext 并不属于某个 Servlet 的配置,而是针对于整个应用的配置,也叫全局的初始化参数。
- 在
标签中,通过 标签来配置。有两个子标签。 :代表全局初始化参数的 key。 :代表全局初始化参数的 value。 <!--配置servletContext--><context-param><param-name>globalEncoding</param-name><param-value>UTF-8</param-value></context-param><context-param><param-name>globalDesc</param-name><param-value>this is a ServletContext</param-value></context-param>
5. ServletContext常用方法
四: 注解开发Servlet
1. Servlet3.0规范
我们使用的是 Tomcat 9 版本。JavaEE 规范要求是 8 。对应的 Servlet 版本应该是 4.x 版本。但是在企业开发中,稳定要远比追求新版本要重要。所以我们会降版本使用,用的是 Servlet 3.1 版本。
- 其实我们之前的操作全都是基于 Servlet 2.5 版本规范的,也就是借助于配置文件的方式。后来随着软件开发逐步的演变,基于注解的配置开始流行。而 Servlet 3.0 版本也就开始支持注解开发了!
- Servlet 3.0 版本既保留了 2.5 版本的配置方式,同时又支持了全新的注解配置方式。它可以完全不需要 web.xml 配置文件,就能实现 Servlet 的配置,同时还有一些其他的新特性,我们在后面的课程中会慢慢学习到。
2. 注解开发的核心
使用注解开发时,就不需要在Web.xml文件里配置Servlet了,而是直接利用注解@WebServlet()在继承HttpSErvlet类的标记,如下:
@WebServlet(value = "/demo1")public class ServletDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doget.....");}}

