【JavaWeb】Servlet

Servlet

一、概述

1、Servlet

Servlet 是一种用于扩展 Java 服务器功能的技术,主要用于开发 Web 应用程序。

  • Servlet 允许在 服务器端 处理 客户端请求 并生成动态内容。(包括动态网页、Web 表单处理、用户会话管理等)
  • Servlet 是 Java EE 规范的一部分,通常用于处理 HTTP 请求和响应。

2、Tomcat

Tomcat 是一个开源的 Java Servlet 容器和 Web 服务器,它实现了 Servlet 规范并提供了运行 Servlet 的环境。

  • Servlet 是一个 Java 类,用于 处理客户端请求 并 生成响应。
  • Tomcat 是一个 Servlet 容器 和 Web 服务器,用于运行和管理 Servlet。

Tomcat 提供了一个实现 Servlet 规范的运行时环境,允许开发者在 Web 环境中运行 Java 应用程序。

3、关系图

接收请求 --> 处理业务 --> 响应结果

在这里插入图片描述

Servlet的执行及方法的调用底层都是由Tomcat完成的。

4、Servlet 的特点

  • 请求处理
    • Servlet 处理客户端(如浏览器)发送的请求,并生成响应。它可以处理表单数据、查询参数、文件上传等。
  • 生命周期管理
    • Servlet 的生命周期包括 初始化、处理请求、销毁 三个阶段。Servlet 容器负责管理这些生命周期阶段。
  • 多线程
    • Servlet 容器通常为每个请求创建一个新的线程来处理,因此多个请求可以并发处理。
  • 状态管理
    • Servlet 可以通过会话(HttpSession)跟踪用户的状态和数据。

5、Tomcat 运行原理

  1. 启动过程:

    当启动 Tomcat 时,它会加载并初始化一系列组件,包括:

    • Connector(连接器):负责处理 客户端 与 Tomcat 之间的网络通信,它监听特定的端口,并接收客户端请求。
    • Engine(引擎):是 Tomcat 处理所有请求的核心组件,它负责将请求路由到适当的虚拟主机(Host)。
    • Host(主机):表示一个虚拟主机,它可以包含多个 Web 应用程序。
    • Context(上下文):表示一个 Web 应用程序,它包含了 Servlet、JSP 等 Web 组件。
  2. 请求处理过程:

    • 当客户端发送请求时,Connector 接收到请求,并将其传递给 Engine。
    • Engine 根据请求的主机名找到相应的 Host,并将请求传递给 Host。
    • Host 根据请求的 URL 找到对应的 Context(Web 应用程序),并将请求传递给 Context。
    • Context 根据请求的 URL 找到对应的 Servlet 或 JSP,并将请求传递给相应的 Servlet 或 JSP 进行处理。
    • Servlet 或 JSP 处理请求,并生成响应,然后将响应返回给客户端。
  3. 部署过程:

    • 可以将 Web 应用程序(WAR 文件或目录)部署到 Tomcat 的 webapps 目录来添加新的 Web 应用程序。
    • Tomcat 会自动检测并加载新部署的 Web 应用程序,然后启动该应用程序,并为其分配一个唯一的上下文路径。
    • SpringBoot 提供了一个内嵌的 Tomcat 服务器,允许你通过简单的 java -jar 命令直接启动应用。
  4. 关闭过程:

    • 当关闭 Tomcat 时,Tomcat 会关闭所有正在运行的 Web 应用程序,并释放占用的资源,然后停止监听端口,最终关闭自身。

二、Servlet 的生命周期

Servlet 的生命周期,指的是 Servlet对象 从 创建 到 销毁 的一个过程。

public interface Servlet {
    // Servlet对象创建时,调用一次该方法
    void init(ServletConfig var1) throws ServletException;

    // 用户每次访问Servlet时,都会调用该方法
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    // Servlet对象销毁时,调用一次该方法
    void destroy();
    
    // 获取 ServletConfig 对象,用于获取 Servlet 的初始化参数和上下文信息。
    ServletConfig getServletConfig();
    
    // 返回 Servlet 的描述信息
    String getServletInfo();
}

1、初始化

Servlet 对象第一次被创建时,容器会调用 init(ServletConfig) 方法进行初始化。

  • init 方法只会在 Servlet 对象创建时被调用一次。

  • init 方法中,可以进行一些初始化操作,如读取配置文件、建立数据库连接、加载资源等。

默认情况下,init 方法是在第一次请求 Servlet 时调用的(懒加载)。如果初始化的数据很多,加载时间较长,给第一个用户的体验不好,因为要等比较久。可以通过 loadOnStartup设置在容器启动时就实例化 Servlet ,同时执行init方法

@WebServlet(value = "/test", loadOnStartup = 5)
public class AnnotatedServlet extends HttpServlet {}
  • loadOnStartup 必须是整数
  • loadOnStartup 默认是 -1,表示第一次访问Servlet才加载
  • loadOnStartup 只要设置大于0,就会在容器启动时加载(数字越小,越先加载)

在 Spring Boot 中,所有的控制器在应用启动时都会被自动加载,因此不需要额外配置 loadOnStartup

2、请求处理

Servlet 初始化完成后,容器会调用 service(ServletRequest, ServletResponse) 方法 处理客户端发送的请求。

  • service 方法 在每次请求 Servlet 时都会调用一次。
  • service 方法 会根据请求类型(GETPOST 等)调用相应的处理方法(如 doGet()doPost() 等)。
  • 在处理完请求后,service 方法会将响应返回给客户端。

3、销毁

Servlet 实例被销毁前,容器会调用 destroy() 方法进行清理工作。

  • destroy 方法只会在 Servlet 销毁时被调用一次。
  • destroy 方法中,可以进行一些资源释放、清理操作,如关闭数据库连接、释放内存等。

4、小结

Servlet 的生命周期由容器负责管理

  • 初始化init() 方法在 Servlet 被加载时调用,进行初始化设置。
  • 请求处理service() 方法处理每个请求,通常不需要直接重写,doGet()doPost() 等方法会被调用。
  • 销毁destroy() 方法在 Servlet 被卸载时调用,进行资源清理。

可以通过重写 init()service()destroy() 等方法来实现自定义的初始化、请求处理和销毁逻辑。

三、Servlet 的实现

1、GenericServlet

GenericServlet 实现了 Servlet,重写了除 service 方法之外的其他方法。

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {

    public ServletConfig getServletConfig() {
        return this.config;
    }

    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

    public void init() throws ServletException {}

    public abstract void service(ServletRequest var1, ServletResponse var2) 
        throws ServletException, IOException;

    public void destroy() {}
    
}

继承 GenericServlet 的话,就不需要实现Servlet接口的5个方法了,只需要重写一个 service 方法就可以了。

2、HttpServlet

HttpServlet 继承于 GenericServlet,并对service方法进行进一步处理。

  1. 先将 ServletRequest 和 ServletResponse 强转为 HttpServletRequest 和 HttpServletResponse。
  2. 然后 根据不同的请求方式,调用对应的处理方法。
public abstract class HttpServlet extends GenericServlet {

    // 将 req 和 res 强转为 HttpServletRequest 和 HttpServletResponse
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request;
        HttpServletResponse response;
        try {
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException var6) {
            throw new ServletException(lStrings.getString("http.non_http"));
        }

        this.service(request, response);
    }

    // 根据不同的请求方式,调用对应的处理方法。
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        if (method.equals("GET")) {
            this.doGet(req, resp);
        } else if (method.equals("HEAD")) {
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }
    }
}

如果处理HTTP请求,可以继承 HttpServlet,只需要重写具体的处理方法即可,例如:doGetdoPost方法 。

3、自定义 Servlet

在 SpringBoot 中 定义并注册自定义 Servlet

@Component
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Hello from MyServlet");
    }

}

@Configuration
public class ServletConfig {

    @Bean
    public ServletRegistrationBean<MyServlet> myServlet() {
        return new ServletRegistrationBean<>(new MyServlet(), "/myServlet");
    }
    
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scj1022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值