request和response对象(疑问:为什么servlet和jsp中可以直接使用req和res对象?如何理解内置的含义?)

时间:2021-02-24 21:05:52

1.  Request 和 Response 对象起到了服务器与客户机之间的信息传递作用。

    Request 对象用于接收客户端浏览器提交的数据,而 Response 对象的功能则是将服务器端的数据发送到客户端浏览器。

   Request 对象

l            从浏览器端取得数据的方法

l           Request.QueryString 集合读取表单 GET 方法数据      

l           Request.Form 集合读取表单 POST 方法数据      

l           Request.ServerVariables 集合读取服务器端环境变量

 

2. 为什么 servlet 和 jsp 中可以直接使用 req 和 res 对象?

自己的理解:(不一定正确,有待学习和理解)

servlet 容器类负责贞听请求,如果捕获到请求,请创建 req 和 res 对象,然后激活 service ()方法,(或者,如果是 get 请求,激活 doGet ()方法;如果是 post ,则激活 doPost ()方法),并且同时也把 req 和 res 对象传递给了 service ()方法(或者是相应的 doGet() 和 doPost() 方法);

也就是说 servlet 容器类贞听到请求后已经自动创建 req 和 res 对象,并传递给 service ()方法了,所以自己编码实现 servlet 的 service ()方法时候,直接使用 req 和 res 对象就可以,因为 service ()方法(由 service 方法根据请求方式再调用相应的 doGet ()和 doPost ()方法) 是容器负责自动调用的,调用的同时也实现的 req 和 res 的传参。 Ok !!

 

问题:迫切需要查看 tomcat 的 javax.servlet.Servlet 接口实现的类来验证自己的理解;

 

参考资料:

Servlet 容器工作原理(一)(二)(三)(四)

http://www.linuxmine.com/45398.html

注释:这是一个通过给出简单实现 servlet 容器的源代码的方式来阐述 servlet 容器( tomcat )工作原理的好资料。

关键内容摘要:

编者注 : 本文和同系列的前面一文“基于 Java 的 Web 服务器工作原理”,都摘自“ Tomcat 运行内幕”一书(一本有关 Tomcat 的教程)。在阅读本文前,最好先阅读前文,以巩固基础信息。在此,将介绍如何建立两个 servlet 容器。 随附本书的应用程序可以下载 ,如果您有兴趣,可以在近段时间内到 作者网站 下载。

 

   本文介绍一个简单 servlet 容器的基本原理。这个 servlet 容器都处理简单的 servlet 及 staticResource 。复杂一些的 servlet 会超出这些容器的容量,您可以从 TOMCAT  运行内幕 一书学习创建复杂的 servlet 容器。

 

 在理解应用程序如何运作之前,您必须熟悉 javax.servlet.Servlet 接口。首先就来介绍这个接口。随后,就介绍 servlet 容器服务 servlet 的具体内容。

 

   javax.servlet.Servlet 接口

 

   servlet 编程,需要引用以下两个类和接口: javax.servlet 和 javax.servlet.http ,在这些类和接口中, javax.servlet.Servlet 接口尤为重要。所有的 servlet 必须实现这个接口或继承已实现这个接口的类。

   Servlet 接口有五个方法,如下:

l         public void init(ServletConfig config) throws ServletException

l         public void service(ServletRequest request, ServletResponse response)  throws ServletException, java.io.IOException

l         public void destroy()

l         public ServletConfig getServletConfig()

l         public java.lang.String getServletInfo()

 

    init 、 service 和 destroy  方法是 Servlet 生命周期的方法。当 Servlet 类实例化后,容器加载 init ,以通知 servlet 它已进入服务行列。 init 方法必须被加载, Servelt 才能接收和请求。如果要载入数据库驱动程序、初始化一些值等等,程序员可以重写这个方法。在其他情况下,这个方法一般为空。

 

   service 方法由 Servlet 容器调用,以允许 Servlet 响应一个请求。 Servlet 容器传递 javax.servlet.ServletRequest 对象和 javax.servlet.ServletResponse 对象。 ServletRequest 对象包含客户端 HTTP 请求信息, ServletResponse 则封装 servlet 响应。 这两个对象,您可以写一些需要 servlet 怎样服务和客户怎样请求的代码。

 

一个功能健全的 servlet 容器对于每个 servlet 的 HTTP 请求会完成以下事情:

 

l         当 servlet 第一次被调用的时候,加载了 servlet 类并调用它的 init 方法(仅调用一次)

l         响应每次请求的时候 ,构建一个 javax.servlet.ServletRequest 和 javax.servlet.ServletResponse 实例。

l         激活 servlet 的 service 方法,传递 ServletRequest 和 ServletResponse 对象。

l         当 servlet 类关闭的时候,调用 servlet 的 destroy 方法,并卸载 servlet 类。

 

发生在 servlet 容器内部的事就复杂多了。只是这个简单的 servlet 容器的功能不很健全,所以,这它只能运行非常简单的 servelt ,并不能调用 servlet 的 init 和 destroy 方法。然而,它也执行了以下动作:

 

l         等待   HTTP 请求。

l         构建 ServletRequest 和   ServletResponse 对象  

l         如果请求的是一个 staticResource ,就会激活 StaticResourceProcessor 实例的 process 方法,传递 ServletRequest 和 ServletResponse 对象。

l         如果请求的是一个 servlet , 载入该类,并激活它的 service 方法,传递 ServletRequest 和 ServletResponse 对象。注意:在这个 servlet 容器,每当 servlet 被请求的时候该类就被载入。

Servlet 容器的关键工作流程 : HttpServer1 类的 await 方法

在这个应用程序中, servlet 容器由六个类组成 。

? HttpServer1

? Request

? Response

? StaticResourceProcessor

? ServletProcessor1

? Constants

  正如前文中的应用程序一样,这个程序的进入口(静态 main 方法)是 HttpServer 类。这个方法创建了 HttpServer 实例,并调用它的 await 方法。这个方法等待 HTTP 请示,然后创建一个 request 对象和 response 对象,根据请求是否是 staticResource 还是 servlet 来分派它们到 StaticResourceProcessor 实例或 ServletProcessor 实例。

代码如下:  

    Listing 2.2. HttpServer1 类的 await 方法

   public void await() {

   ServerSocket serverSocket = null;

   int     port   = 8080;

  

   try {

   serverSocket =   new ServerSocket(port, 1,

   InetAddress.getByName("127.0.0.1"));

     }

   catch (IOException e) {

   e.printStackTrace();

   System.exit(1);

     }

  

   // 循环,等待一个请求

   while (!shutdown) {

   Socket socket     = null;

   InputStream input   = null;

   OutputStream output = null;

  

   try {

   socket = serverSocket.accept();// 贞听用户请求;

   input   = socket.getInputStream();

   output = socket.getOutputStream();

  

   // 如果捕获用户请求,则创建请求对象并解析

   Request request = new Request(input);

   request.parse();

  

   // 创建回应对象

   Response response = new Response(output);

   response.setRequest(request);

  

   // 检测是否是 servlet 或静态资源的请求

   //servlet 请求以 "/servlet/" 开始

   if (request.getUri().startsWith("/servlet/")) {

   ServletProcessor1 processor = new ServletProcessor1();

// 激活 process ( req , res )方法,并同时把 req 和 res 实例传递给 process ()方法;

// 在 tomcat 中,激活的是 service ( req , res )方法(或者相应的 doGet 和 doPost 方法)

   processor.process(request, response);

         }

   else {

   StaticResourceProcessor processor =

   new StaticResourceProcessor();

   processor.process(request, response);

         }

   // 关闭 socket

   socket.close();

  

   // 检测是否前面的 URI 是一个 shutdown 命令

   shutdown = request.getUri().equals(SHUTDOWN_COMMAND);

       }

   catch (Exception e) {

   e.printStackTrace();

   System.exit(1);

       }

     }

   }

   如果 URI 中包含 "/servlet/." ,请求推进到后面,否则,请求传递到 StaticResourceProcessor 实例。

Ok !

 

3. 如何理解内置的含义?(不一定正确,有待学习和理解)

http://topic.csdn.net/t/20060211/20/4551196.html

问:

如何深入理解内置对象  

  最好是在实现原理层次上

答:

tomcat 的体系中,有个 jsp   parser ,它的作用是把 jsp 页面 parse 成 java 程序( servlet ),然后再运行 parse 出来的 servlet ,由此可见, 9 个内置对象就是 jsp   parser 在根据 jsp 页面生成 servlet 的时候自动创建的 java 对象或容器中已经创建的对象。