一:Servlet(掌握)

1.Servlet概述

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

2.Servlet执行过程分析

image.png

3.Servlet类视图

image.png

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的是线程不安全的。
  • 解决方法:

    • 将成员定义到doGet或者doPost方法内部,或者使用同步代码块保证功能同步。
    • 若只有在初始化时给成员赋值,而其他时间不改变成员,那也是安全的。

      5.3 Servlet的声明和映射

      Servlet的声明和映射都在Web.xml文件里书写,其中映射方式有3种,声明方式只有一种。
  • Servlet的声明,通过反射机制创建Servlet对象

    1. <!--声明Servlet-->
    2. <servlet>
    3. <!--给Servlet起一个名字-->
    4. <servlet-name>studentServlet</servlet-name>
    5. <!--Servlet的全限定类名-->
    6. <servlet-class>com.itheima.servlet.StudentServlet</servlet-class>
    7. </servlet>
  • Servlet的映射(3种)

  1. 第一种
    具体名称的方式。访问的资源路径必须和映射配置完全相同。

    1. <!--servlet映射-->
    2. <servlet-mapping>
    3. <servlet-name>studentServlet</servlet-name>
    4. <url-pattern>/studentServlet</url-pattern>
    5. </servlet-mapping>
  2. 第二种
    / 开头 + 通配符的方式。只要符合目录结构即可,不用考虑结尾是什么。

    1. <!--通配符*代表任意字符-->
    2. <servlet-mapping>
    3. <servlet-name>studentServlet</servlet-name>
    4. <url-pattern>/studentServlet/*</url-pattern>
    5. </servlet-mapping>
  3. 第三种
    通配符 + 固定格式结尾的方式。只要符合固定结尾格式即可,不用考虑前面的路径。

    1. <servlet-mapping>
    2. <servlet-name>stuServlet4</servlet-name>
    3. <url-pattern>*.do</url-pattern>
    4. </servlet-mapping>

    5.4 Servlet的创建时机(了解)

  4. 第一次访问时创建
    优势:减少对服务器内存的浪费。提高了服务器启动的效率。
    弊端:如果有一些要在应用加载时就做的初始化操作,无法完成。

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

5.5 默认Servlet(了解)

默认Servlet是由服务器提供的一个Servlet,它配置在Tomcat的conf目录下的web.xml中。如下图所示:
image.png
它的映射路径是<url-pattern>/<url-pattern>,我们在发送请求时,首先会在我们应用中的web.xml中查找映射配置,找到就执行,这块没有问题。但是当找不到对应的Servlet路径时,就去找默认Servlet,由默认Servlet处理。所以,一切都是Servlet。

二:ServletConfig(了解)

1. ServletConfig概述

  • ServletConfig 是 Servlet 的配置参数对象,在 Servlet 的规范中,允许为每一个 Servlet 都提供一些初始化的配置。所以,每个 Servlet 都有一个自己的 ServletConfig。
  • 作用:在 Servlet 的初始化时,把一些配置信息传递给 Servlet。
  • 生命周期:和 Servlet 相同。

image.png

2. ServletConfig的使用

  • 标签中,通过标签来配置。有两个子标签。类似于键值对形式。
  • :代表初始化参数的 key。
  • :代表初始化参数的 value。

    1. <!--ServletConfig配置-->
    2. <servlet>
    3. <servlet-name>ServletConfig</servlet-name>
    4. <servlet-class>com.itheima.servlet.ServletConfigDemo1</servlet-class>
    5. <!--配置ServletConfig-->
    6. <init-param>
    7. <param-name>encoding</param-name>
    8. <param-value>UTF-8</param-value>
    9. </init-param>
    10. <init-param>
    11. <param-name>desc</param-name>
    12. <param-value>this is a config</param-value>
    13. </init-param>
    14. </servlet>

    常用方法:
    image.png

    三:ServletContext(掌握)

    1. ServletContext介绍

  • ServletContext 是应用上下文对象(应用域对象)。每一个应用中只有一个 ServletContext 对象。

  • 作用:可以获得应用的全局初始化参数和达到 Servlet 之间的数据共享。
  • 生命周期:应用一加载则创建,应用被停止则销毁。

image.png
ps:可以把ServletContext对象看成一个全局仓库,不同的Servlet对象可以在这个仓库中存东西,拿东西,即Servlet对象共享这个仓库。

2. 域对象概念

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

    3. 如何获取ServletContext对象

    方法一:通过调用ServletConfig对象的getServletContext()方法。

    1. public class ServletDemo9 extends HttpServlet {
    2. //定义Servlet配置对象ServletConfig
    3. private ServletConfig servletConfig;
    4. //在初始化时为ServletConfig赋值
    5. @Override
    6. public void init(ServletConfig config) throws ServletException {
    7. this.servletConfig = config;
    8. }
    9. @Override
    10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    11. //1.获取ServletContext对象
    12. ServletContext servletContext = servletConfig.getServletContext();
    13. System.out.println(servletContext);
    14. }
    15. }

    方法二:在GenericServlet类中,已经为我们声明了ServletContext获取的方法,如下图:
    image.png
    因为我们的类继承HttpServlet,而HttpServlet又是GenericServlet的子类,所以我们在获取ServletContext时,如果当前Servlet没有用到它自己的初始化参数时,就可以不用再定义初始化参数了,而是直接调用父类的getServletContext()方法就行了 。

    1. @Override
    2. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    3. ServletContext servletContext = super.getServletContext();
    4. }

    4. ServletContext配置方式

  • ServletContext 并不属于某个 Servlet 的配置,而是针对于整个应用的配置,也叫全局的初始化参数。

  • 标签中,通过标签来配置。有两个子标签。
  • :代表全局初始化参数的 key。
  • :代表全局初始化参数的 value。

    1. <!--配置servletContext-->
    2. <context-param>
    3. <param-name>globalEncoding</param-name>
    4. <param-value>UTF-8</param-value>
    5. </context-param>
    6. <context-param>
    7. <param-name>globalDesc</param-name>
    8. <param-value>this is a ServletContext</param-value>
    9. </context-param>

    5. ServletContext常用方法

    image.pngimage.png

    四: 注解开发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 的配置,同时还有一些其他的新特性,我们在后面的课程中会慢慢学习到。

image.png

2. 注解开发的核心

使用注解开发时,就不需要在Web.xml文件里配置Servlet了,而是直接利用注解@WebServlet()在继承HttpSErvlet类的标记,如下:

  1. @WebServlet(value = "/demo1")
  2. public class ServletDemo1 extends HttpServlet {
  3. @Override
  4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  5. System.out.println("doget.....");
  6. }
  7. }