Servlet,Session和Cookie以及属性作用域
Servlet,Session和Cookie
Servlet
Servlet的生命周期
Servlet的生命周期很简单,只有一个主要的状态:初始化。如果Servlet没有初始化,那么要么正在初始化(运行其构造函数或init()
方法),正在撤销(运行destroy方法),要么就是还不存在。
Web容器首先加载Servlet类,然后初始化Servlet(运行其构造函数),接着调用init()
方法,它在Servlet的一生中只调用一次,而且必须在容器调用service()
之前完成。
接下来就需要调用service()
方法来处理客户的请求,每个请求都在一个单独的线程中运行。详细过程如下:用户点击一个链接,链接的URL指向一个Servlet;容器识别出请求指向的Servlet,创建请求对象和响应对象,并根据请求URL找到Servlet;然后容器为这个请求创建或分配一个线程,调用Servlet的service()
方法,此时会将响应和请求对象作为参数。这个时候service()
方法会根据HTTP方法确定要调用哪个Servlet中的方法(doGet,doPost等)。方法调用结束后Servlet使用响应对象将响应写至客户,响应通过容器传回,service()
方法结束。此时线程要么撤销,要么返回到容器管理的一个线程池,而请求和响应对象则失去了意义。
最后容器则是调用destroy()
方法,从而在Servlet被杀死(即可以垃圾回收)之前有机会清理资源。与init()
一样,destroy()
也只能调用一次。
一个客户请求意味着一个新的线程,也就是一个新的service()
方法,尽管可能是在一个Servlet中。请求不同,线程不同。
Servlet生命周期中的三个重要时刻
- init()方法:在Servlet实例创建之后,且能为客户请求提供服务之前。它能让你Servlet在处理客户请求之前有机会对其进行初始化。
- service()方法:在一个客户请求到来的时候,容器会开始一个新线程,或者从线程池中分配一个线程,并调用Servlet的service()方法。这个方法的作用是查看请求,确定HTTP方法,并在Servlet上调用对应的方法(doGet,doPost等)
- doXXX()方法:service()方法根据请求的HTTP方法来调用,作用是实现web应用的功能。
ServletConfig和ServletContext
ServletConfig是Servlet的配置对象,容器在初始化的时候通过它传递信息给Servlet。它在容器初始化Servlet的时候创建,同时容器为它提供Servlet初始化参数的键值对的引用。它只能被设置一次,就是在容器初始化Servlet的时候。每个Servlet都有一个ServletConfig。
ServletContext是上下文对象,提供了一系列方法提供Servlet与Web容器交互。它在启动的时候被创建,同时容器为它提供上下文初始化参数的键值对的引用。上下文初始化参数不能修改,但是上下文属性可以修改,而且非线程安全。整个web应用只有一个ServletContext。
Session与Cookie
HTTP协议使用的是无状态连接,连接只为一个请求/响应而存在。由于连接不会持久保留,所以容器认不出做第二个请求的客户与做前一个请求的客户是否为同一个客户。对容器而言,每个请求都来自于一个新客户。
容器一般使用会话ID来区分客户:对客户的第一个请求,容器会生成一个唯一的会话ID,并通过响应将它返回给客户,客户在以后的请求中发回这个会话ID。最常用的方式是通过cookie来交换这个会话ID信息。
属性作用域
可访问性 | 作用域 | 适用于 | |
---|---|---|---|
ServletContext | Web应用的所有部分 | Servlet的生命期,即所部署应用的生命期 | 希望整个应用共享的资源 |
HttpSession | 访问整个特定会话的所有Servlet或jsp | 会话的生命期 | 与客户会话有关的资源和数据,要与客户完成一个持续的会话 |
Request | 应用中能直接访问请求对象的所有部分 | 请求的生命期,即 Servlet的service()方法结束 | 将模型信息从控制器传递到视图,或特定于单个客户请求的任何其他数据 |