关于Servlet

JavaWeb基础

Posted by YD Blog on October 14, 2022

关于Servlet

概述

  • Servlet是Java提供的一门动态web资源开发技术
  • Servlet是JavaEE规范之一,其实就是一个接口,我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet

使用

  • 引入依赖

在pom文件中添加依赖

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <!-- proviede表示仅在调试状态使用此软件包,打包时忽略它,这是由于在服务器软件里有集成此软件包 -->
      <scope>provided</scope>
    </dependency>
  • 继承接口,使用注解开发的格式
@WebServlet("需要使用此servlet实现的页面地址")
public class ServletDemo implements Servlet {
    //实现Servlet接口中的方法
}
  • 访问

启动服务器,浏览器输入URL访问该Servlet

Servlet执行流程

servlet对象由web服务器创建,方法由web服务器调用。

浏览器访问页面时,服务器会自动创建对应注解的servlet对象,并根据浏览器的请求调用对应的方法响应请求。

Servlet生命周期

生命周期:对象的生命周期指一个对象从创建到被销毁的整个过程

Servlet运行在Servlet容器(Web服务器)中,其生命周期由容器来管理,分为四个阶段:

  1. 加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象
  2. 初始化:在Servlet实例化后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次
  3. 请求处理:每次请求Servlet时,Servlet容器都会调用Servlet()方法对请求进行处理
  4. 服务终止:当需要释放内存或者容器关闭时,容器都会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收

另外,在注解时可以通过添加其他参数来修改Servlet实例化时机:

@WebServlet(urlPatterns = "/",loadOnStartup = 1)
//loadOnStratup参数设置为负整数时,在第一次访问时创建Servlet对象
//若为0或者正整数,服务器启动时创建Servlet对象,数字越小优先级越高

Servlet对象的方法

在官方文档中是如此描述的:

返回值 方法名 参数列表 何时调用 功能
void init() ServletConfig servlet 容器仅在实例化 servlet 之后调用 init 方法一次。在 servlet 可以接收任何请求之前,init 方法必须成功完成 由 servlet 容器调用,指示将该 servlet 放入服务
ServletConfig getServletConfig() void 此接口的实现负责存储 ServletConfig 对象,以便此方法可以返回该对象。实现此接口的 GenericServlet 类已经这样做了 返回 ServletConfig 对象,该对象包含此 servlet 的初始化和启动参数。返回的 ServletConfig 对象是传递给 init 方法的对象
void service() (ServletRequest req, ServletResponse res 此方法仅在 servlet 的 init() 方法成功完成之后调用,应该为抛出或发送错误的 servlet 设置响应的状态代码 由 servlet 容器调用,以允许 servlet 响应某个请求
String getServletInfo() void 此方法返回的字符串应该是纯文本,不应该是任何种类的标记(比如 HTML、XML,等等) 返回有关 servlet 的信息,比如作者、版本和版权
void destroy() void 此方法仅在 servlet 的 service 方法已退出或者在过了超时期之后调用一次。在调用此方法之后,servlet 容器不会再对此 servlet 调用 service 方法 由 servlet 容器调用,指示将从服务中取出该 servlet,此方法为 servlet 提供了一个清除持有的所有资源(比如内存、文件句柄和线程)的机会,并确保任何持久状态都与内存中该 servlet 的当前状态保持同步

注意:Servlet是一个对象,除了要实现这几个方法以外没有过多的要求,和其他类一样可以设置成员变量并且进行赋值。

Servlet体系结构

  • Servlet:Servlet体系根接口
  • GenericServlet:Serlet抽象实现类
  • HttpServlet:对HTTP协议的Servlet实现类

若继承HttpServlet实现类,则只需要实现doGet()和doPost()方法即可。

官方对HttpServlet的描述为:

提供将要被子类化以创建适用于 Web 站点的 HTTP servlet 的抽象类。HttpServlet 的子类至少必须重写一个方法,该方法通常是以下这些方法之一:
doGet,如果 servlet 支持 HTTP GET 请求
doPost,用于 HTTP POST 请求
doPut,用于 HTTP PUT 请求
doDelete,用于 HTTP DELETE 请求
init 和 destroy,用于管理 servlet 的生命周期内保存的资源
getServletInfo,servlet 使用它提供有关其自身的信息
几乎没有理由重写 service 方法。service 通过将标准 HTTP 请求分发给每个 HTTP 请求类型的处理程序方法(上面列出的 doXXX 方法)来处理它们。
同样,几乎没有理由重写 doOptions 和 doTrace 方法。
servlet 通常运行在多线程服务器上,因此应该意识到 servlet 必须处理并发请求并小心地同步对共享资源的访问。共享资源包括内存数据(比如实例或类变量)和外部对象(比如文件、数据库连接和网络连接)。

urlPattern配置

  • Servlet想要被访问,必须配置其访问路径(urlPattern)
    1. 一个Servlet可以配置多个urlPattern@WebServlet(urlPatterns={"/demo1","/demo2"})
    2. urlPattern配置规则
      • 精准匹配
      • 配置路径:@WebServlet("/user/select")
      • 访问路径:localhost:8080/web-demo/user/select * 目录匹配
      • 配置路径:@WebServlet("/user/*")
      • 访问路径:localhost:8080/web-demo/user/aaa * 扩展名匹配
      • 配置路径:@WebServlet("/user/*.do")
      • 访问路径:localhost:8080/web-demo/user/aaa.do * 任意匹配
      • 配置路径:@WebServlet("/")或者@WebServlet("/*")
      • 访问路径:localhost:8080/web-demo/haha2333

//*的区别:当项目中配置了/,会覆盖掉Tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时都会走这个Servlet,而若是配置了/,意味着匹配任意访问路径。

由于默认的Servlet是用于处理静态资源的Servlet,被覆盖则不能访问静态资源,故最好不要使用任意匹配。

urlPattern匹配优先级:精确路径>目录匹配>扩展名路径>/*>/