一、Session机制
session机制采用的是在服务器端保持 HTTP 状态信息的方案 。
服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否包含了一个session标识(即sessionId),如果已经包含一个sessionId则说明以前已经为此客户创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数)。如果客户请求不包含sessionId,则为此客户创建一个session并且生成一个与此session相关联的sessionId,这个session
id将在本次响应中返回给客户端保存。
二、保存SessionID的方式
①.保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
②.由于cookie可以被人为的禁用,必须有其它的机制以便在cookie被禁用时仍然能够把session id传递回服务器,经常采用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。
Session Cookie
session通过SessionID来区分不同的客户, session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie,这称之为session cookie,以区别persistent cookies(也就是我们通常所说的cookie),session cookie是存储于浏览器内存中的,并不是写到硬盘上的,通常看不到JSESSIONID,但是当把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,这时地址栏看到
session cookie针对某一次会话而言,会话结束session cookie也就随着消失了,而persistent cookie只是存在于客户端硬盘上的一段文本。
关闭浏览器,只会是浏览器端内存里的session cookie消失,但不会使保存在服务器端的session对象消失,同样也不会使已经保存到硬盘上的持久化cookie消失。
三、Session的生命周期
1)什么时候创建HTTPSession对象?
①:对于JSP:浏览器访问访问服务器端的任何一个JSP,服务器都会立即创建一个HttpSession对象?
不一定.
*若当前的JSP 是客户端访问的当前WEB 应用的第一个资源,且 JSP 的 page 指定的session属性为false,则服务器就不会为JSP创建一个HttpSession对象
*若当前JSP不是客户端访问的当前WEB应用的第一个资源,且其他页面已经创建一个HttspSession对象,则服务器也不会为当前JSP页面创建一个HttpSession对象,而会把和当前会话相关的那个HTTPSession对象返回给当前的JSP页面
②:对于Servlet::若 Servlet 是客户端访问的第一个WEB应用的资源,则只有调用了request.getSession() 或 request.getSession(true) 才会创建HTTPSession对象
2)page 指令 的session="false" 到底什么意思
*当前JSP页面禁用session隐含变量!但可以使用其他的显示的 HttpSession对象
3)在Servlet 中 如何获取HTTPSession对象?
*request.getSession(boolean create):当create 为 false 时,若没有和当前JSP页面关联的 Httpsession 对象,返回null,若有则返回 HttpSession 对象。
当create为 true ,一定会返回 HttPSession 对象,若没有和当前JSP页面关联的HTTPSession对象,则服务器会创建一个新的HTTPSession对象,若有关联,则直接返回关联的。
*request..getSession()等同于request.getSession(true)
4)什么时候销毁HttpSession对象
①.直接调用 HttpSession 的 invalidate() 方法:立刻是HTTPSession对象失效
②.服务器卸载了当前 WEB 应用
③.超出了 HTTPSession 的过期时间
* 设置HttpSession的过期时间,调用session.setMaxInactiveInterval(int x); 单位是秒
* 在Tomcat 的 WEB.xml中设置 (单位是分钟,如果session不设置生命周期,就会使用这个默认的)
<session-config>
<session-timeout>30</session-timeout >
</session-config>
④. 并不是关闭了浏览器就销毁了 session ,所以说要访问到Session对象,可以通过持久化Cookie 和 URL重写 两种方式 。
详细看 HttpSession API
代码示例
login.jsp
<span style="font-family:KaiTi_GB2312;font-size:18px;"><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> SessionID: <%=session.getId() %><br><br> IsNew: <%=session.isNew() %><br><br> MaxInactiveInternal: <%=session.getMaxInactiveInterval() %><br><br> createTime: <%=session.getCreationTime() %><br><br> lastAccessTime: <%=session.getLastAccessedTime() %><br><br> <% Object username = session.getAttribute("username"); if(username == null){ username = ""; } %> <form action="hello.jsp" method="post"> <%--<form action="<%=response.encodeURL("hello.jsp") %>" method="post">--%> // 如果客户端的Cookie处于禁用状态,就要使用URL重写 username:<input type="text" name="username" value="<%=username %>" /> <input type="submit" name="Submit" /> </form> </body> </html></span>
hello.jsp
<span style="font-family:KaiTi_GB2312;font-size:18px;"><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> SessionID: <%=session.getId() %><br><br> IsNew: <%=session.isNew() %><br><br> MaxInactiveInternal: <%=session.getMaxInactiveInterval() %><br><br> createTime: <%=session.getCreationTime() %><br><br> lastAccessTime: <%=session.getLastAccessedTime() %><br><br> Hello:<%=request.getParameter("username") %><br> <%-- <a href="login.jsp?username= <%= request.getParameter("username") %> ">重新登录</a> 采用设置属性的方式比较好--%> <% session.setAttribute("username",request.getParameter("username")); %> <%-- <%=response.encodeURL("login.jsp") %> <%=response.encodeURL("logout.jsp") %> URL重写--%> <a href="login.jsp">重新登录</a> <a href="logout.jsp">注销</a> </body> </html></span>
logout.jsp
<span style="font-family:KaiTi_GB2312;font-size:18px;"><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> SessionID: <%=session.getId() %><br><br> IsNew: <%=session.isNew() %><br><br> MaxInactiveInternal: <%=session.getMaxInactiveInterval() %><br><br> createTime: <%=session.getCreationTime() %><br><br> lastAccessTime: <%=session.getLastAccessedTime() %><br><br> Bye:<%=session.getAttribute("username") %><br><br> <a href="login.jsp?">重新登录</a> <% session.invalidate();//杀死session %> </body> </html></span>
HttpSession接口中的方法
getId方法
getCreationTime方法
getLastAccessedTime方法 setMaxInactiveInterval方法
getMaxInactiveInterval方法 isNew方法
如果客户端请求消息中返回了一个与Servlet程序当前获得的HttpSession对象的会话标识号相同的会话标识号,则认为这个HttpSession对象不是新建的。
invalidate方法 getServletContext方法
setAttribute方法 getAttribute方法
removeAttribute方法 getAttributeNames方法
HttpServletRequest接口中的Session方法
getSession方法
public HttpSession getSession(boolean create)
public HttpSession getSession()
isRequestedSessionIdValid方法
isRequestedSessionIdFromCookie方法
isRequestedSessionIdFromURL方法
利用URL重写实现Session跟踪
Servlet规范中引入了一种补充的会话管理机制,它允许不支持Cookie的浏览器也可以与WEB服务器保持连续的会话。这种补充机制要求在响应消息的实体内容中必须包含下一次请求的超链接,并将会话标识号作为超链接的URL地址的一个特殊参数。
将会话标识号以参数形式附加在超链接的URL地址后面的技术称为URL重写。如果在浏览器不支持Cookie或者关闭了Cookie功能的情况下,WEB服务器还要能够与浏览器实现有状态的会话,就必须对所有可能被客户端访问的请求路径(包括超链接、form表单的action属性设置和重定向的URL)进行URL重写。
HttpServletResponse接口中定义了两个用于完成URL重写方法:
encodeURL方法
encodeRedirectURL方法