[toc]
第三章 Servlet 容器模型
Web容器在启动时会加载每个Web应用程序,并为每个Web应用程序创建唯一的一个ServletContext实例对象。
3.1 ServletContext接口(⭐⭐⭐)
整个项目只有一个ServletContext对象
3.1.1 得到ServletContext引用
ServletContext sc = getServletContext();
ServletContext sc = getServletConfig().getServletContext();
3.1.2 获取应用程序的初始化参数
ServletContext对象是在Web应用程序装载时初始化的。
检索Servlet上下文初始化参数指定应用程序范围内的信息。
public String getInitParameter(String name)
-
public Enumeration getInitParameterNames()
在web.xml中设置初始化参数
<servlet-context>
<param-name>email</init-name>
<param-value>15454521@163.com</param-value>
</servlet-context>
注意,<servlet-context>
元素是针对整个应用的,所以并不嵌套在某个<servlet>
中。该元素是<web-app>
的直接子元素
Servlet上下文初始化参数与Servlet初始化参数是不同的,前者是属于整个web应用的,后者是属于定义它们的Servlet的,不能被web应用程序其它组件访问。
3.1.3 通过ServletContext对象获得资源
-
public URL getResource(String path)
: 路径必须以"/"开头,它相对于该Web应用程序的文档根目录。 -
public InputStream getResourceAsStream(String path)
: 从资源上获得InputStream对象 - p59
3.1.4 登陆日志(⭐)
p60
3.1.5 使用RequestDispatcher实现请求转发
-
RequestDispatcher getRequestDispatcher(String name)
: 参数path表示资源路径,它必须以"/"开头,表示相对于web应用的文档根目录。 -
RequestDispatcher getNamedDispatcher(String name)
: 参数name为一个命名的Servlet对象。
ServletContext的getRequestDispatcher与ServletRequest的getRequestDispatcher区别是,前者只能传递以"/"开头的路径,而后者可以传递一个相对路径。
例如:request.getRequestDispatcher("../html/copyright.html")
是合法的
3.1.6 使用ServletContext对象存储数据(⭐⭐⭐⭐)
该对象也是一个作用域对象,它的作用域是整个应用程序。
public void setAttribute(String name, Object object)
public Object getAttribute(String name)
public Enumeration getAttributeValues(String name)
public void removeAttribute(String name)
3.2 会话管理(⭐⭐⭐)
3.2.1 理解状态与会话
协议记住用户及其请求的能力称为状态
- HTTP的无状态特征
服务器无法确定多个请求是来自相同的客户还是不同的客户。 - 会话的概念
会话是一个客户与服务器之间的不间断的请求响应序列。当一个客户向服务器发送第一个请求时就开始了一个会话。对该客户之后的每个请求,服务器都能识别出来请求来自同一个客户。
3.2.2 会话管理机制
- 当客户向服务器发送第一个请求时,服务器就可以为该客户创建一个HTTPSession会话对象,并将请求对象与该会话对象关联。服务器在创建会话对象时为其指定一个唯一标识符,称为会话ID。
- 当服务器向客户发送响应时,服务器将该会话ID与响应数据一起发送给客户
- 客户在接受到响应后将会话ID存储在浏览器的内存中。当客户再次向服务器发送一个请求时,它将通过Cookie请求头把会话ID与请求一起发送给服务器。
- 服务器接收到请求后,从请求对象中取出会话ID,在服务器中查找之前创建的会话对象,找到后将该请求与之前创建的ID值相同的会话对象关联起来。
注意:不能使用客户的ID地址唯一标识客户。因为,客户可能时通过局域网访问Internet。尽管在局域网中每个客户有一个IP地址,但对于服务器来说,客户的实际IP地址是路由器的IP地址,所以该局域网的所有客户的IP地址都相同,因此无法唯一标识客户。
3.2.3 HttpSession API
public String getId()
-
public long getCreationTime()
: 返回会话创建时间 - ...
-
public boolean isNew()
: 如果会话对象还没有同客户关联,则返回true -
public ServletContext getServletContext()
: 返回该会话所属的ServletContext对象 public void setAttribute(String name, Object value)
public Object getAttribute(String name)
- ...
3.2.4 使用HttpSession对象
共三步:
- 创建或返回与客户请求关联的会话对象。
-
public HttpSession getSession(boolean create)
: 返回或创建与当前请求关联的会话对象。如果没有与当前请求关联的会话对象,当参数为true时创建一个新的会话对象,当参数为false时返回null。 -
public HttpSession getSession()
: 该方法与调用getSession(true)等价。
-
- 在会话对象中添加或删除"名/值"对属性
- 如果需要可使会话失效
3.2.5 会话超时与失效
设置会话超时时间, 0或者小于0表示会话永不过期。这种设置方法针对web应用程序的所有会话对象,但有时需要对特定的会话对象指定超时时间,可使用会话对象的setMaxInactiveInterval()
<session-config>
<session-timeout>10</session-timeout>
</session-config>
如果没有这样进行设置,默认时间为30分钟。
手动销毁对象可使用HttpSession接口的invalidate()
3.3 Cookie及其应用
3.3.1 Cookie API
构造方法public Cookie(String name, String value)
常用方法:
-
public String getName()
: 返回Cookie名称 -
public String getValue()
: 返回Cookie的值 public void setValue(String newValue)
public void setMaxAge(int expiry)
public int getMaxAge()
- p64
3.3.2 向客户端发送Cookie
- 创建Cookie对象
Cookie userCookie = new Cookie("username", "hacker");
- 设置Cookie的最大存活时间
- 在默认情况下,发送到客户端的Cookie对象只是一个会话级别的Cookie,它存储在浏览器内存中,用户关闭浏览器后Cookie对象将被删除。如果希望浏览器将Cookie对象存储到磁盘上,需要使用Cookie类的
setMaxAge()
设置Cookie的最大存活时间。userCookie.setMaxAge(60*60824*7);
- 在默认情况下,发送到客户端的Cookie对象只是一个会话级别的Cookie,它存储在浏览器内存中,用户关闭浏览器后Cookie对象将被删除。如果希望浏览器将Cookie对象存储到磁盘上,需要使用Cookie类的
- 向客户发送Cookie对象
- 要将Cookie对象发送到客户端,需要调用响应对象的
addCookie()
将Cookie添加到SetCookie响应头。response.addCookie(userCookie);
- 要将Cookie对象发送到客户端,需要调用响应对象的
3.3.3 从客户端读取Cookie
从客户端得到Cookies,调用请求对象的getCookies()
,该方法返回一个Cookies数组
- 调用请求对象的
getCookies()
Cookie[] cookies = request.getCookies();
- 对Cookie数组循环
- 调用每个Cookie的getName()直到找到一个与希望的名称相同的对象为止。
3.3.4 Cookie的安全问题
p69
3.3.5 实例:用Cookie实现自动登陆
p70
网友评论