一.会话
HTTP协议是一种无状态的协议,作为 web 服务器,必须能够采用一种机制来唯一地标识
一个用户,同时记录该用户的状态
WEB应用中的会话是指一个客户端浏览器与WEB服务器之间连续发生的一系列请求和响应过程
会话状态是指WEB服务器与浏览器在会话过程中产生的状态信息
为使WEB服务器端程序要能从大量的请求消息中区分出哪些请求消息属于同一个会话,浏览器对其发出的每个请求消息都进行标识
属于同一个会话中的请求消息都附带同样的标识号,这个标识号就称之为会话ID(SessionID)
在 Servlet 规范中,常用以下两种机制完成会话跟踪
–Cookie
–Session
二.Cookie
cookie机制:在客户端保持 HTTP 状态信息的方案
Cookie是在浏览器访问WEB服务器的某个资源时,由WEB服务器在HTTP响应消息头中附带传送给浏览器的一个小文本文件
一旦WEB浏览器保存了某个Cookie,那么它在以后每次访问该WEB服务器时,都会在HTTP请求头中将这个Cookie回传给WEB服务器
WEB服务器通过在HTTP响应消息中增加Set-Cookie响应头字段将Cookie信息发送给浏览器,浏览器则通过在HTTP请求消息中增加Cookie
请求头字段将Cookie回传给WEB服务器
浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB;
Cookie的发送和接收:
Servlet API中提供了一个javax.servlet.http.Cookie类来封装Cookie信息:
package javax.servlet.http; import java.text.MessageFormat; import java.util.ResourceBundle; public class Cookie implements Cloneable { private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings"; private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings"); private String name; private String value; private String comment; private String domain; private int maxAge = -1; private String path; private boolean secure; private int version = 0; private static final String tspecials = ",; "; public Cookie(String name, String value)//一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE) { if ((!isToken(name)) || (name.equalsIgnoreCase("Comment")) || (name.equalsIgnoreCase("Discard")) || (name.equalsIgnoreCase("Domain")) || (name.equalsIgnoreCase("Expires")) || (name.equalsIgnoreCase("Max-Age")) || (name.equalsIgnoreCase("Path")) || (name.equalsIgnoreCase("Secure")) || (name.equalsIgnoreCase("Version")) || (name.startsWith("$"))) { String errMsg = lStrings.getString("err.cookie_name_is_token"); Object[] errArgs = new Object[1]; errArgs[0] = name; errMsg = MessageFormat.format(errMsg, errArgs); throw new IllegalArgumentException(errMsg); } this.name = name; this.value = value; } //setter和getter //clone() }
cookie的发送:
1.新建cookie
2.设置cookie最大有效期:setMaxAge(int)
3.将Cookie放入到HTTP响应报头
HttpServletResponse接口中定义了一个addCookie方法,它用于在发送给浏览器的HTTP响应消息中增加一个Set-Cookie响应头字段。
说明:
1.创建了一个cookie,不设置最大有效期,默认情况下它是一个会话级别的cookie; 存储在浏览器的内存中,用户退出浏览器之后被删除;
2.若设置了最大有效期,那么浏览器将该cookie存储在磁盘上,该cookie直到指定的有效期才删除,将最大时效设为0则是命令浏览器删除该cookie
Cookie接收:
HttpServletRequest接口中定义了一个getCookies方法,它用于从HTTP请求消息的Cookie请求头字段中读取所有的Cookie项,遍历cookie数组,获取
有用的cookie
cookie的作用范围:
默认cookie可以作用于当前目录和当前目录的子目录,不能作用于当前目录的上级目录
可以用setPath(String uri)设置cookie的作用范围,其中/表示站点的根目录
eg. cookie.setPath(request.getContextPath());//request.getContextPath()返回当前web应用的根目录
三.Seesion
session机制采用的是在服务器端保持 HTTP 状态信息的方案
过程:
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否包含了一个session标识(即sessionId),
若已经包含一个sessionId,服务器就按照session id把这个session检索出来使用(用(如果检索不到,可能会新建一个,这种情况可能出
现在服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数),如果客户请求不包含
sessionId,则为此客户创建一个session并且生成一个与此session相关联的sessionId,这个session id将在本次响应中返回给客户端保存。
保存sessionId的两种方式:
(1)采用cookie:浏览器可以自动的按照规则把sessionId发送给服务器
(2)URL重写:把session id附加在URL路径的后面;附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面
说明:
1.默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie,即session cookie,session cookie是存储于浏览器内存中的,并不是
写到硬盘上的,通常看不到JSESSIONID,它的maxAge属性一般为-1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,因此同一机器的两个
浏览器窗口(通过双击浏览器图标打开)访问服务器时, 会生成两个不同的Session,由浏览器窗口内的链接、脚本等打开的新窗口除外这类子窗口会共享父
窗口的Cookie;与session cookie区别的称为persistent cookie,是存在于客户端硬盘上的一段文本;
2.当浏览器禁用cookie后,就采用URL重写的方式传递Sessionid
3.关闭浏览器,存储于浏览器内存中的session cookie,存在服务器端的session对象不会消失,存到硬盘上的持久化cookie也不会消失
Session的生命周期:
1.session的创建
Sessinon在用户访问第一次访问JSP、Servlet等程序时才会创建并调用request.getSession()或request.getSession(true)时创建session,但是注意以下几点:
(1)访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session;
(2)若JSP的page指令,设置了session=“false”,那么JSP中不会创建HttpSession对象,但是你可以自己定义HttpSession对象
其实<%@ page session="false"%>表示当前JSP禁用隐式session对象,但是可以使用显示的HttpSession对象
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ page session="false" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>session生命周期</title> </head> <body> <% HttpSession session = request.getSession();//获取当前请求的session,若无则新建session,等同于request.getSession(true) //HttpSession session request.getSession(true);//获取当前请求的session,若无并且create=true则新建session,若无且create=false则返回null %> Session ID:<%=session.getId() %> Create time:<%=new Date(session.getCreationTime()) %> </body> </html>
注意:获取session的两个方法:request.getSession()和request.getSession(boolean create);
2.session的删除
(1) 服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效(注:关闭浏览器,服务器中的session不会失效);
session.setMaxInactiveInterval(int);//单位为秒,设置session失效时间
还可以在tomcat的web.xml中设置session的默认失效时间,单位为分钟,Tomcat中Session的默认失效时间为30分钟:
<!-- ==================== Default Session Configuration ================= -->
<!-- You can set the default session timeout (in minutes) for all newly -->
<!-- created sessions by modifying the value below. -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
(2)调用Session的invalidate方法
(3)服务器进程被停止
URL重写
即将会话标识号以参数形式附加在超链接的URL地址后面
在浏览器不支持Cookie或者关闭了Cookie功能的情况下,必须对所有可能被客户端访问的请求路径(包括超链接、form表单的action
属性设置和重定向的URL)进行URL重写,实现有状态的会话
HttpServletResponse接口中定义了两个用于完成URL重写方法:
encodeURL(String url)
encodeRedirectURL(String url)
session应用练习:
1.购物车
2.session防表单重复提交