Servlet 是如何与 Web 服务器(如 Tomcat, Jetty)协作的?它们之间的接口是什么?

Web 服务器本身主要负责接收客户端的原始 HTTP 请求(通过网络连接),并将其初步处理。但它并不知道如何执行特定的 Java 代码来生成动态内容。这就是 Web 容器(它是 Web 服务器的一个组成部分或一个独立的组件,例如 Tomcat 既是 Web 服务器也是 Web 容器)的作用。

Web 容器知道如何加载和管理 Java Web 应用(WAR 文件),如何找到应用中的 Servlet,以及如何根据进来的 HTTP 请求将处理任务分发给对应的 Servlet。

核心的协作机制是基于 Java Servlet API 定义的一套标准接口和类。

相应的接口 (The Interfaces):

Servlet API 是 Java EE (现在是 Jakarta EE) 规范的一部分,它定义了 Web 容器和 Servlet 之间交互的契约。主要的接口和类包括:

  1. javax.servlet.Servlet 接口:

    • 这是所有 Servlet 都必须实现的根接口(继承 GenericServletHttpServlet 来间接实现)。
    • 它定义了 Servlet 的生命周期方法 (init(), service(), destroy()) 和配置方法 (getServletConfig(), getServletInfo())。
    • 它是 Web 容器调用 Servlet 的入口。 Web 容器通过这个接口与 Servlet 实例进行通信。
  2. javax.servlet.ServletRequest 接口:

    • 代表客户端发来的请求。
    • 提供了获取请求信息的方法,如参数、属性、输入流等。
    • 这是一个通用的请求接口,与具体协议无关。
  3. javax.servlet.ServletResponse 接口:

    • 代表服务器要发送回客户端的响应。
    • 提供了设置响应状态码、头部信息、获取输出流等方法。
    • 这是一个通用的响应接口,与具体协议无关。
  4. javax.servlet.http.HttpServletRequest 接口:

    • 继承自 ServletRequest,专门用于处理 HTTP 请求。
    • 提供了更多 HTTP 特有的方法,如获取请求方法 (GET/POST)、URI、URL、Header、Cookie、Session 等。
    • Web 容器会创建实现了此接口的对象,并将它传递给 Servlet 的处理方法。
  5. javax.servlet.http.HttpServletResponse 接口:

    • 继承自 ServletResponse,专门用于生成 HTTP 响应。
    • 提供了更多 HTTP 特有的方法,如设置 HTTP 状态码、重定向、设置 Content-Type、获取用于写入文本或二进制数据的 Writer/OutputStream。
    • Web 容器会创建实现了此接口的对象,并将它传递给 Servlet 的处理方法,Servlet 通过操作此对象来构建响应。
  6. javax.servlet.ServletConfig 接口:

    • 代表 Servlet 的配置信息,在 Servlet 初始化时由容器传递给 init() 方法。
    • 可以获取 Servlet 的名称以及初始化参数。
  7. javax.servlet.ServletContext 接口:

    • 代表整个 Web 应用的上下文环境。
    • 提供对 Web 应用级别资源的访问,如应用初始化参数、日志记录、请求分发器 (RequestDispatcher) 等。
    • 它是在整个 Web 应用生命周期内都存在的对象,可以用于在不同 Servlet 之间共享信息。

协作过程:

  1. 部署与启动: 我们在开发过程中将包含 Servlets 的 Web 应用(通常打包成 WAR 文件)部署到 Web 容器中。容器在启动时会读取应用的部署描述符 (web.xml) 或扫描注解 (@WebServlet) 来发现和加载 Servlets。
  2. 初始化 (init): 当容器首次需要使用一个 Servlet 实例(或者在容器启动时配置为立即加载)时,容器会创建该 Servlet 的实例,并调用其 init(ServletConfig config) 方法进行初始化,传入一个由容器创建的 ServletConfig 对象。
  3. 接收请求: Web 服务器接收到客户端的 HTTP 请求后,如果该请求的 URL 匹配某个 Servlet 的映射规则,服务器会将请求转交给其内部的 Web 容器处理。
  4. 创建请求和响应对象: Web 容器根据接收到的原始 HTTP 请求数据,创建出实现了 HttpServletRequestHttpServletResponse 接口的 具体实现类 的对象。这些实现类是 Web 容器提供的,它们封装了原始 HTTP 请求的所有细节和用于构建响应的方法。
  5. 调用服务方法 (service / doGet / doPost):
    • 容器找到负责处理该 URL 的 Servlet 实例(容器会维护一个 Servlet 实例池,避免重复创建)。
    • 容器调用该 Servlet 实例的 service(ServletRequest req, ServletResponse resp) 方法。
    • 对于继承 HttpServlet 的 Servlet,其默认的 service 方法会根据请求的 HTTP 方法(GET, POST 等)进一步调用对应的 doGet(HttpServletRequest req, HttpServletResponse resp)doPost(HttpServletRequest req, HttpServletResponse resp) 方法。
    • 容器将步骤 4 中创建的 HttpServletRequestHttpServletResponse 对象作为参数传递给 Servlet 的处理方法。
  6. Servlet 处理逻辑: Servlet 在其 doGetdoPost 等方法中,利用传入的 HttpServletRequest 对象获取请求信息(参数、头部等),执行业务逻辑,然后利用 HttpServletResponse 对象设置响应状态码、头部,并将要返回给客户端的数据写入到响应的输出流中。
  7. 发送响应: 当 Servlet 的处理方法执行完毕返回后,Web 容器会接管 HttpServletResponse 对象。容器负责将该对象中包含的响应状态码、头部信息和写入到输出流中的响应体数据,格式化为标准的 HTTP 响应报文,并通过底层的网络连接发送回客户端浏览器。
  8. 销毁 (destroy): 当 Web 应用被卸载或容器关闭时,容器会调用 Servlet 实例的 destroy() 方法,允许 Servlet 释放资源。

总结:

Servlet 和 Web 服务器(容器)之间的协作完全依赖于 Java Servlet API 定义的标准接口。Web 容器充当了 Servlet 的宿主环境和调用者。它接收原始的 HTTP 请求,将其封装成 HttpServletRequest 对象,创建 HttpServletResponse 对象用于构建响应,然后调用 Servlet 实例上定义好的方法(如 service, doGet, doPost),并将这两个对象作为参数传递进去。Servlet 代码只需要关注如何使用这些标准接口对象来处理请求和生成响应,而无需关心底层网络通信的细节。这种标准化的接口机制确保了 Servlet 可以在任何实现了 Servlet API 的 Web 容器中运行,极大地提高了代码的可移植性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冰糖心书房

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

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

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

打赏作者

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

抵扣说明:

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

余额充值