2.请求和响应的处理

本章目标

  1. 动态资源和静态资源
  2. Servlet体系
  3. Serviet生命周期(重点)

本章内容:

一、动态资源和静态资源

1、静态资源

静态资源:一般客户端发送请求到web服务器,web服务器从内存在取到相应的文件,返回给客户端,客户端解析并渲染显示出来

常见资源有:html、 css、 js、 图片等

在静态Web程序中,客户端使用Web浏览器(IE、FireFox等)经过网络(Network)连接到服务器上,使用HTTP协议发起一个请求(Request),告诉服务器我现在需要得到哪个页面,所有的请求交给Web服务器,之后WEB服务器根据用户的需要,从文件系统(存放了所有静态页面的磁盘)取出内容。之后通过Web服务器返回给客户端,客户端接收到内容之后经过浏览器渲染解析,得到显示的效果。

2、动态资源

动态资源:一般客户端请求的动态资源,先将请求交于web容器,web容器连接数据库,数据库处理数据之后,将内容交给web服务器,web服务器返回给客户端解析渲染处理。

常见资源有:.jsp.asp/.aspx.php

如果客户端请求的是动态资源(.jsp、.asp/.aspx、.php),则先将请求转交给WEB Container(WEB容器),在WEB Container中连接数据库,从数据库中取出数据等一系列操作后动态拼凑页面的展示内容,拼凑页面的展示内容后,把所有的展示内容交给WEB服务器,之后通过WEB服务器将内容发送回客户端浏览器进行解析执行。

动态资源需要在服务器端运行,响应给客户端是服务器端代码的运行结果

3、javax.servlet(包)

Servlet相关的接口都放在javax.servlet 包中,常用接口有:

接口 说明
Servlet 处理请求和发送响应的过程的Java技术
ServletConfig 在初始化的过程中由 Servlet容器使用
ServletContext 定义在Servlet用于获取来自其容器的信息的方法
ServletRequest 向服务器发送的请求信息
ServletResponse 客户端请求的响应
ServletInputStream 用于从客户端读取二进制数据
ServletOutputStream 用于将二进制数据发送到客户端

二、Servlet体系

1、Servlet简介

Servlet 是一个用 Java 编写的程序,此程序在服务器上运行以处理客户端请求,处理请求的过程如下:

  1. 接收客户端(浏览器)请求信息
  2. 调用业务处理
  3. 向客户端(浏览器)发送HTTP响应

2、HttpServlet

HttpServlet 类是一个抽象类,用以创建针对HTTP协议的 Servlet接口的实现类,它实现了service方法;

针对客户端不同的消息发送方式,分别调用doGet()、doPost()等方法,因此在继承HttpServlet时只需要覆盖doGet或doPost方法即可,一般不推荐直接覆盖service方法

 // doGet() 方法处理客户端作出的 GET 请求。
 protected void doGet(HttpServletRequest request,
      HttpServletResponse response)throws ServletException,IOException{}
 
 // doPost() 方法处理客户端作出的 POST 请求。
 protected void doPost(HttpServletRequest request,
      HttpServletResponse response)throws ServletException,IOException{}

3、Servlet生命周期

启动tomcat:环境准备,解析web.xml文件(获取配置信息,验证文件内容的配置格式是否正确),如果配置有问题,在服务器启动的时候就会报错

3.1、生命周期分类

Servlet的生命周期是由servlet的容器来控制的。分为3个阶段:初始化阶段、运行阶段、销毁阶段。

阶段 时机 调用的方法(钩子)
实例化 Servlet 容器创建 Servlet 的实例 默认构造方法
初始化 第一次向服务器发送请求或者服务器上没有servlet的时候,实例化之后 init(config)
服务 每次向服务器发送请求的时候 service()
销毁 服务停止的时候,项目重新加载的时候 destroy ()
不可用 销毁实例并标记为垃圾收集 等待GC回收

虽然这里提到了五个阶段,实际我们涉及到的只有三个即:初始化阶段、运行阶段、销毁阶段

3.2、详细执行流程

Servlet部署在容器中,它的生命周期由容器管理。Servlet的生命周期始于将它装入Web服务器的内存时,并在终止或重新装入Servlet时结束。

Servlet的生命周期可以归纳为以下几个阶段:

  1. 装载Servlet:这项操作一般是动态执行的。有些服务器提供了响应的管理功能,可以在启动的时候就装载Servlet并能够初始化特定的Servlet。
  2. 创建一个Servlet实例。
  3. 调用Servlet的init()方法。
  4. 一个客户端的请求到达服务器。
  5. 创建一个请求对象。
  6. 创建一个响应对象。
  7. 激活Servlet的Service()方法,并传递请求和响应对象。
  8. Service()方法获得关于请求对象的信息、处理请求、访问其它资源、获得需要的信息。
  9. Service()方法使用响应对象的方法,将响应传回服务器,最终到达客户端。
  10. 对于更多的客户端请求,服务器创建新的请求和响应对象,仍然激活此Servlet的Service()方法,将两个对象作为参数传递给它。
  11. 当服务器不再需要Servlet或当服务器关闭时,服务器将会调用Servlet的destroy()方法来销毁Servlet。

3.3、Servlet初始化的情况

只调用一次

当web应用处于运行阶段时,特定的servlet被客户端首次请求访问。

在web.xml文件中为servlet设置了<load-on-startup>元素

 <servlet>
 <servlet-name>servlet1</servlet-name>
 <servlet-class>servlet.servlet1</servlet-class>
 <load-on-startup>0</load-on-startup>
 </servlet>

在servlet的配置当中,5的含义是:标记容器是否在启动的时候就加载这个servlet。

当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;

当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。正数的值越小,启动该servlet的优先级越高。

当web应用被重新启动时,web应用中的所有servlet会在特定的时间被重新初始化。

3.4、运行阶段

多次调用执行

在这个阶段servlet可以随时响应客户端的请求。当servlet容器接到访问特定的servlet请求时,servlet容器会创建针对与这个请求的servletRequest和servletResponse对象,然后调用service()方法,并把这两个对象当做参数传递给service()方法。Service()方法通过servletRequest对象获得请求信息,并处理该请求,再通过servletResponse对象生成响应结果。

不管是post还是get方法提交,都会在service中处理,然后,由service来交由相应的doPost或doGet方法处理,如果你重写了service方法,就不会再处理doPost或doGet了,如果重写sevice()方法,可以自己转向doPost()或doGet()方法

当servlet容器把servlet生成的响应结果发送给客户后,servlet容器会销毁servletRequest和sevletResponse对象。

3.5、销毁阶段

只执行一次

当Web应用被终止时,servlet容器会先调用web应用中所有的servlet对象的destroy()方法,然后在销毁servlet对象。此外容器还会销毁与servlet对象关联的servletConfig对象。

在destroy()方法的实现中,可以释放servlet所占用的资源。如关闭文件输入输出流,关闭与数据库的连接。

3.6、服务流程

如果配置文件中没有设置<load-on-startup> ,那么Servlet对象的创建工作将是在请求到达的时候再会创建,然后进行初始等相关操作。如图所示:

三、Request对象

1、什么是请求对象

Request对象封装了客户端对服务器的请求信息

实现javax.servlet.http.HttpServletRequest接口

使用 HTTP 协议处理客户端的请求

2、ServletRequest

ServletRequest接口封装了客户端请求的细节。它与协议无关,并指定一个HTTP的子接口。

ServletRequest主要功能有:

  • 找出客户端的主机名和IP地址
  • 检索请求参数
  • 取得和设置属性
  • 取得输入、输出流

ServletRequest类的常用方法:

  • getAttribute(String name): 返回具有指定名称的请求属性,如果不存在则返回null。属性可由Servlet引擎设置或使用
  • setAttribute()显式加入。
  • getAttributeName(): 返回请求中所有属性名的枚举。如果不存在属性,则返回一个空的枚举。
  • getCharacteEncoding(): 返回请求所用的字符编码。
  • getInputStream()throws IOException: 返回与请求相关的(二进制)输入流。可以调用getInputStream()或getReader()方法。
  • getParameter(String name): 返回指定输入参数,如果不存在,返回null。
  • getParameterName(): 返回请求中所有参数名的一个可能为空的枚举。
  • getParameterValues(String name): 返回指定输入参数名的取值数组,如果取值不存在则返回null。它在参数具有多个取值的情况下十分有用。

3、HttpServletRequest处理请求

HttpServletRequest类型的对象代表的是请求对象,父接口:ServletRequest

所在包为:javax.servlet.http

常用方法

  • getParameter: 得到客户端的请求参数信息
  • getMethod: 得到客户端的请求方式,返回GET或者POST
  • getRequestDispatcher: 得到请求转发器
  • setAtrribute(): 给请求范围中设置数据
  • getAttribute(): 取出请求范围的数据

四、Response对象

1、什么是影响对象

由服务器端程序生成的响应

通过 HTTP 协议将响应发送给客户端

2、ServletResponse

ServletResponse将一个Servlet生成的结果传送到发出请求的客户端。ServletResponse操作主要是作为输出流及其内容类型和长度的包容器,它由Servlet引擎创建。

ServletResponse接口常用方法有以下几种:

  • getCharacterEncoding(): 返回响应程序使用字符解码的名字。除非显式设置,否则为ISO-8859-1。
  • getOutputStream()throws IOException: 返回用于将返回的二进制输出写入客户端的流,此方法和getWrite()方法二者只能调用其一。
  • getWriter()throws IOException: 返回用于将返回的文本输出写入客户端的一个字符写入器,此方法和getOutputStream()二者只能调用其一。
  • setContentType(String type): 设置内容类型。在HTTPServlet中设置Content-Type头标。

3、HttpServletResponse处理响应

HttpServletResponse类型的对象代表的是响应对象,父接口ServletResponse类型

HttpServletResponse代表了对客户端的Http的响应。它提供了表示状态码、状态信息和响应头标的方法,同时还负责对URL中写入一个Web页面的HTTP会话ID进行解码。JSP中的内建对象response是一个HttpServletResponse实例。

所在包为:javax.servlet.http

3.1、接口常用方法:

  • addCookie(Cookie cookie): 将一个Set-Cookie头标加入到响应。
  • setHeader(String name,String value): 设置具有指定名字和取值的一个响应头标。
  • encodeRedirectURL(String url): 如果客户端不知道接受cookie,则向URL加入会话ID。第一种形式只对在sendRedirect()中使用的URL进行调用。其它被编码的URL应被传递到encodeURL()中。
  • encodeURL(String url): 使用URL和一个SessionID重写这个URL。
  • sendRedirect(String location): 把响应发送到另一页面或者Servlet进行处理。
  • getWriter(): 该方法取得PrintWriter对象,来输出字符数据。
  • getOutputStream(): 该方法获得ServletOutputStream输出流。
  • setContentType(): 该方法设置响应的MIME类型。
  • setCharacterEncoding(String charset): 设置响应的字符编码类型。

3.2、示例

跳转我们先不处理

 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 {
     String CONTENT_TYPE = "text/html; charset=GBK";
       //设置响应的MIME类型
     response.setContentType(CONTENT_TYPE);
     //获得输出流对象
     PrintWriter out = response.getWriter();
     out.println("Hello World!<br>");
     out.println("你好,世界!");
     out.close();
     //跳转到login.jsp页面
     response.sendRedirect("login.jsp");
 }

五、web开发中请求转发和重定向的区别(了解)

从a中去b:

  • 请求转发:
    • 执行过程:由a请求转发的B,第一次向a发送请求,a在服务器端将请求对象和响应对象转给b,最后由b给客户端浏览器响应,过程中一次请求,一次响应
    • 是否共享请求对象及响应对象: a和b是共享请求和响应对象的
    • 浏览器端是否知情:浏览器不知情
    • 地址兰路径: 不会变化,显示的是第一次请求的路径
    • 应用上的区别:如果由a向带一些结构比较复杂的数据去B(比如集合,比如一个实体类对象),肯定要使用请求转发
    • 路径最前面的/:路径最前面的/代表的是项目的根目录
  • 重定向
    • 执行过程:重定向:由a重定向b,第一次向a发送请求,a告诉客户端浏览器,让客户端浏览器再去请求b,最后由b给客户端做响应,整个过程中两次请求,两次响应
    • 是否共享请求对象及响应对象: a和b不共享请求和响应、
    • 浏览器端是否知情:浏览器知情
    • 地址栏路径:浏览器的地址栏显示的是最后一次请求的路径,
    • 应用上的区别:a并不带数据去b,那就使用重定向
    • 路径最前面的/:路径最前面的/代表的是tomcat服务的根目录
posted @ 2025-04-23 17:32  icui4cu  阅读(20)  评论(0)    收藏  举报