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 对象或容器中已经创建的对象。