Servlet – 执行流程
Servlet 提供了一种与客户端请求通信并基于请求-响应编程模型生成动态响应的方法。 Servlet 可以响应任何类型的请求,但在大多数情况下,这些请求用于由 Web 服务器托管的 Web 应用程序。对于这些应用程序, Java Servlet 定义了 HTTP – 特定的 servlet 类。为了编写 Servlet, Java Servlet API 在javax.servlet和javax.servlet.http包中提供了接口和类。 servlet 接口定义了 servlet 的生命周期。我们必须扩展GenericServlet类或HTTPServlet类(特定于 HTTP 请求/响应)来处理 Web 应用程序中的客户端请求。
Servlet 的执行流程
在为提供的客户端请求执行 servlet 时,servlet 容器在 Servlet 生命周期中起着至关重要的作用。
小服务容器:
它是一个 Web 容器,是与Java Servlet 交互的 Web 服务器的一部分。 Servlet 容器负责
- 管理 servlet 的生命周期
- 创建 servlet 对象、请求和响应对象
- 将 URL 映射到特定的 servlet
- 确保 URL 请求者具有正确的访问权限
- 管理 JSP 页面等的执行,
在执行应用程序客户端组件之前,应将其部署到容器中。所有这些 Web 组件和容器都在 Web/应用程序服务器上运行。
小服务程序:
为了理解 servlet 的执行流程,我们将创建一个简单的 Web 应用程序来在客户端浏览器中显示 hello 消息。在本例中,我们将使用 Eclipse IDE 和 Tomcat 服务器。创建以下文件,如下面的包目录结构所示。
例子
要创建的文件:
- 在 Eclipse 中创建“动态 Web 应用程序”项目。
- 创建“ index.html”文件以在请求中从客户端获取输入。
- 创建“ HelloServlet. Java”来处理请求并生成响应。
- 创建“ web.xml”文件以指定到相应 servlet 的 URL 映射。
索引.html:
创建以下表单以将用户名作为来自客户端浏览器的输入。
HTML
Home
Java
package com;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Get the client entered data from request object
String name = request.getParameter("name");
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println("Hello " + name + "!!
");
out.close();
}
}
XML
ServletFlow
index.html
HelloServlet
com.HelloServlet
HelloServlet
/hello
你好Servlet。Java:
在下面创建 servlet 以接受客户端请求、处理它并生成响应。
Java
package com;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Get the client entered data from request object
String name = request.getParameter("name");
// set the response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Print hello message to the client browser in
// response object
out.println("Hello " + name + "!!
");
out.close();
}
}
网页.xml:
创建部署描述符 - web.xml 文件以提及欢迎文件并将 URL 映射到 Servlet 类。
XML
ServletFlow
index.html
HelloServlet
com.HelloServlet
HelloServlet
/hello
程序执行
- 右键单击项目,“运行方式->在服务器上运行”
- 在服务器启动的同时,Web 应用程序将部署在服务器上。
第1步:
下面是应用部署后的servlet容器的概念图。
如上图所示,
在服务器端:
- Servlet 容器在主服务器中可用,Web 应用程序部署到 servlet 容器中。
- 在容器内部,我们有以下文件夹结构。
- Web 应用程序——在本例中,“ ServletFlow”
- 在那个 WEB-INF 文件夹中——我们有到 servlet 名称的 URL 映射。
- 在 WEB-INF、web.xml 文件和 classes 文件夹内维护“ HelloServlet.class ”文件。Java”
在客户端:
- 浏览器将可用于在 HTTP 请求中发送客户端数据并从服务器接收 HTTP 响应。
- 该协议将根据 IP 地址和端口号在客户端和服务器之间建立虚拟套接字连接。
第2步:
当我们启动服务器时,servlet 容器的工作是
- 识别所有 Web 应用程序
- 部署这些 Web 应用程序和
- 为每个应用程序准备一个单独的对象。这个对象是“ servletContext”对象。
在部署 Web 应用程序时,
- 容器将识别 WEB-INF 文件夹下的web.xml文件。
- 在识别出 web.xml 文件后,容器会执行 web.xml 文件的加载、解析和读取其中的内容。
- 如果 web.xml 文件中有任何应用程序级数据(如显示名称或上下文参数),容器将获取该应用程序数据并将其存储在“ servletContext ”对象中。此数据由 servlet 上下文对象管理。
现在,容器将根据“ web.xml”文件中提到的“欢迎文件列表”识别要在客户端浏览器上显示的欢迎文件页面。在这里,我们将“ index.html”指定为欢迎文件。因此,它将该 HTML 页面显示给浏览器。网址: http://localhost:8081/ServletFlow/
一旦我们输入名称并单击提交,那么一个请求将与客户端输入的数据进行协议。
第 3 步:
- 该协议将准备请求格式,它有两部分,请求头和请求体。
- 请求标头包含有关客户端浏览器的详细信息。
- 例如:请求方法类型、协议信息、客户端浏览器接受的语言、cookies信息客户端浏览器支持的编码机制等,
- 在用户表单中输入的实际数据将以请求参数的形式存储在请求正文中。
- 协议会将这个请求格式传送到主服务器。
- 然后服务器会检查请求是否有效。
- 如果它是有效的,它会将该请求转发到 servlet 容器。
- 现在,容器将识别要执行的应用程序名称和资源名称。
- 容器将根据扩展名和资源名称检查请求是否为 HTML 请求。
- 正如我们在表单中指定的,容器将根据与 classes 文件夹下的“ HelloServlet.class”文件关联的 URL 模式(“ hello”)来识别要执行的 servlet。
- 为了识别它,容器将用于应用程序、WEB-INF 文件夹和 web.xml 文件。
- 在 web.xml 文件中,映射详细信息可用。因此容器将根据 URL 模式获取特定的 servlet,然后容器将查看 classes 文件夹并搜索所需的 .class 文件。
- 一旦容器识别出 servlet .class 文件,servlet 的生命周期就会开始。
第 4 步:Servlet 生命周期
Servlet 加载:
- 第一个容器将执行 Servlet 加载。
- 容器将检查相同的 servlet 是否已经可用,如果没有,则将 .class 文件、字节码加载到内存中。
- 为此,容器将调用class c = class.forName(“helloServlet”);内部。
Servlet 实例化:
- servlet 加载后,它为 servlet 创建一个对象。
- 它为该 servlet 创建“ servletConfig”对象,并将该特定 servlet 的所有数据存储在其中。
- 为此,容器将调用object obj = c.newInstance();内部。
小服务程序初始化:
- 现在我们需要初始化 servlet,容器将通过传递servletConfig对象来调用init() 。
- 首先,容器将执行参数化的 init() 方法。在其中,将从通用 servlet 调用另一个无参数的 init() 方法,并且该方法也将被执行。
- 现在,容器将创建 HTTP 请求和 HTTP 响应对象以及执行 dopost() 方法的线程。
- 在 GenericServlet 的情况下,第一个容器将调用通用 servlet 中的 service() 方法,绕过 servlet 请求和 servlet 响应对象作为参数。
- 在这里,由于这是 HTTP 特定请求,我们使用的是 HTTPServlet,我们需要通过传递Http servlet 请求和Http servlet 响应来执行doPost()方法。
- 然后容器将访问 doPost() 方法。最后,该请求到达 servlet 的 dopost() 方法。
- HTTP 请求对象的目的是存储客户端指定的数据。它主要有3种数据,Request headers,Request parameters data,和Request attributes data。
- 请求标头:存储有关客户端浏览器的信息。
- 请求参数数据:存储客户端输入的实际信息以供处理。
- 请求属性数据:存储在执行 servlet 时生成的任何动态数据。
- 一旦执行了“doPost()”方法,就会在响应对象中生成响应。
- 当容器到达 doPost() 方法执行的末尾时,该线程将被销毁,并且容器将将该响应分派给主服务器。
- 主服务器将 HTTP 响应传输到协议。
- 该协议将准备一个具有响应头和响应正文的响应格式。
- 响应标头:它包含元数据,例如即将到来的响应类型、响应的长度等。
- 响应正文:要在客户端浏览器中显示的实际动态响应。
第 5 步:
- 该协议将该响应对象传送到客户端浏览器。
- 浏览器会从响应体中获取数据并显示在浏览器中。
- 当响应显示在客户端时,协议将破坏客户端和服务器之间的连接。
- 然后容器将了解响应已分派给客户端,并将销毁请求对象和响应对象。
- 现在容器将处于等待进一步请求的状态。
- 根据容器实现和应用服务器,容器将销毁 servlet。
- 例如:在 Tomcat 服务器的情况下,容器会一直等到服务器关闭。在 Weblogic 服务器的情况下,它将等待服务器中指定的时间。
- 因此,当应用程序完成工作并且服务器停止时,容器将销毁 servlet 配置对象,然后销毁 servlet 对象。
- 销毁 servlet 对象只不过是通过调用destroy()方法取消实例化 servlet。
- 容器将从内存中卸载 servlet 字节码并销毁“ServletContext”对象。
结论
Java Servlet 没有main()方法。 Servlet Container 的工作是实例化 servlet 或创建一个新线程来处理请求和响应对象。为了在单个 servlet 中处理多个请求,容器创建了多个线程。您还可以通过定义侦听器对象在 servlet 的生命周期中监视和响应这些事件。当生命周期事件发生时,监听器对象中的方法被调用。