Servlet工作流程、类图、请求转发、重定向解读

Servlet工作过程

图示:

请添加图片描述

文字:

  1. 客户端向服务器端发送HTTP请求
  2. 服务器端容器解析该请求
  3. 容器去创建Servlet实例
  4. 调用Servlet实例的 init() 方法
  5. 调用Servlet实例的 service() 方法
  6. Servlet实例向容器输出响应信息
  7. 容器将响应信息回传给客户端
  8. 容器调用Servlet实例的 destroy() 方法

容器与实例关系

Servlet 接口 定义了 Servlet 与 Servlet 容器之间的契约,

Servlet 容器将 Servlet 类载入内存,并在 Servlet 实例上调用具体的方法。

用户请求致使 Servlet 容器调用 Servlet 的Service 方法,并传入一个 ServletRequest 实例和一个 ServletResponse 实例

方法详情

init():

在 Servlet 实例化后,Servlet 容器会调用该方法,初始化该对象。init() 方法有一个类型为 ServletConfig 的参数,Servlet 容器通过这个参数向 Servlet 传递配置信息。 Servlet 使用 ServletConfig 对象从 Web 应用程序的配置信息中获取以名-值对形式提供的初始化参数。

Tomcat 初始化一个 Servlet 时,会将该 Servlet 的配置信息封装到一个 ServletConfig 对象中,通过调用 init(ServletConfig config) 方法将 ServletConfig 对象传递给 Servlet。

service():

容器调用 service() 方法来处理客户端的请求。

destroy():

Servlet 的销毁方法。容器在终止 Servlet 服务前调用此方法。最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的

getServletConfig():

该方法返回容器调用 init() 方法时传递给 Servlet 对象的 ServletConfig 对象,ServletConfig 对象包含了 Servlet 的初始化参数。

getServletInfo():

返回一个 String 类型的字符串,其中包括了关于 Servlet 的信息。例如作者、描述信息等。

Servlet类关系图:

请添加图片描述

GenericServlet 类

是一个抽象类,实现了 Servlet 和 ServletConfig 接口,其作用是:
(1)将 init 方法中的 ServletConfig 赋给一个类中成员(ServletConfig config),以便可以通过调用 get ServletConfig 获取。
(2)为 Servlet 接口中的所有方法提供默认的实现。
(3)可以通过覆盖没有参数的 init 方法来编写初始化代码,ServletConfig 则仍然由 GenericServlet 实例保存。
(4)开发者可以在不用获得 ServletConfig 对象情况下直接调用 ServletConfig 的方法,例如上述代码中的 getServletContext() 方法。

HttpServlet 类

覆盖了 GenericServlet 中的 Service 方法,并添加了一个新 Service 方法。

新 Service 方法接受的参数是 HTTPServletRequest 和 HttpServletResponse ,而不是 ServletRequest 和 ServletResponse。

原始的 Service 方法将 Servlet 容器的 request 和 response 对象分别转换成 HTTPServletRequest 和 HttpServletResponse,并调用新的 Service 方法。

HTTPServlet 中的 Service 方法会检验用来发送请求的 HTTP 方法(通过调用 request.getMethod)并调用以下方法之一: doGet、doPost、doHead、doPut、doTrace、doOptions 和 doDelete。这 7 种方法中,doGet 和 doPost 是最常用的。所以,不再需要覆盖 Service 方法了,只须覆盖 doGet 或者 doPost 即可。

HttpServletRequest 接口

继承自 ServletRequest 接口,专门用来封装 HTTP 请求消息。

由于 HTTP 请求消息分为请求行、请求消息头和请求消息体3部分,故而在 HttpServletRequest 接口中定义了获取请求行、请求消息头和请求消息体的相关方法,以及存取请求域属性的方法。

HttpServletResponse 接口

继承自 ServletResponse 接口,专门用来封装 HTTP 响应消息。

由于 HTTP 响应消息分为状态行、响应消息头、消息体三部分,于是在 HttpServletResponse 接口中也相应定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。

ServletContext 接口

Servlet 容器在启动一个 Web 应用时,会为该应用创建一个唯一的 ServletContext 对象供该应用中的所有 Servlet 对象共享。

Servlet 对象可以通过 ServletContext 对象来访问容器中的各种资源。

获得 ServletContext 对象可以通过以下两种方式:

  • 通过 ServletConfig 接口的 getServletContext() 方法获得 ServletContext 对象。
  • 通过 GenericServlet 抽象类的 getServletContext() 方法获得 ServletContext 对象,实质上该方法也调用了 ServletConfig 的 getServletContext() 方法。

Servlet 重定向和请求转发

  • 请求转发

    • 只是把请求转发给服务器上(通常是同一个 Web 应用中)的另一个组件( Servlet 或 JSP等)
    • 请求转发发生在服务器端,由服务器(比如 Servlet)控制
    • 请求转发使用 RequestDispatcher 对象的 forward() 或 include()方法。
    • 请求转发使用 RequestDispatcher 对象的 forward() 或 include()方法。
    • 请求转发后可以在服务器端获取本次请求对象上保存的信息
      • 比如在 Servlet 中将用户名保存到当前 request 对象中,转发给另一组件(如 JSP )后,另一组件可以通过 request 对象取得用户名信息。
    • 请求转发后,浏览器地址栏 URL 不会发生改变。

    RequestDispatcher 对象是通过调用 HttpServletRequest 对象的getRequestDispatcher()方法得到的,所以 forward() 或 include() 本质来说是属于请求对象的方法,所以请求转发始终发生在一个请求当中。

    • 方法

      • forward():

        表示在服务器端从一个 Servlet 中将请求转发到另一个资源(Servlet、JSP 或 HTML 等),本意是让第一个组件对请求做些预处理(或者什么都不做),而让另一组件处理并返回响应。

      • include():表示在响应中包含另一个资源(Servlet、JSP 或 HTML 等)的响应内容,最终被包含的页面产生的任何响应都将并入原来的 response 对象,然后一起输出到客户端。

  • 重定向

    • 则只是告诉客户(浏览器)去访问另一个 URL(可能是同一个 Web 站点甚至其他站点)。
    • 重定向发生在客户端,由客户(通常是浏览器)控制。
    • 重定向则使用 HttpServletResponse 对象的 sendRedirect() 方法。
    • 重定向后则无法在服务器端获取第一次请求对象上保存的信息。
      • 比如还是在 Servlet 中将用户名保存到当前 request 对象中,并重定向到一个新的 URL,然后在新 URL 指向的地址中(假设是某个 Servlet)就无法获取原先保存在第一个请求中的信息。很明显,用户名是保存在第一次请求的对象中,但并没有保存在本次(第二次)请求的对象中。
    • 重定向后,浏览器地址栏 URL 变为新的 URL(因为浏览器确实给新的 URL 发送了一个新的请求)。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值