1、HTTP协议是一种无状态的协议
在Servlet规范中,常用的两种机制完成回话跟踪:
1、Cookie
2、Session
Session机制
session机制采用的是在服务器端保持HTTP状态信息的方案
1、当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否包含了一个session标识(即JSESSIONID)
2、 如果已经包含一个JSESSIONID则说明以前已经为此客户创建过session,服务器就按照JSESSIONID把这个session检索出来使用。
3、如果客户请求不包含JSESSIONID,则为此客户创建一个session并且生成一个与此session相关联的JSESSIONID,这个JSESSIONID将在本次响应中返回给客户端保存
session由服务器创建,浏览器发送第一次请求,服务器会给创建一个JSESSIONID发送给浏览器,创建session的两种方式:HttpServletRequest.getSession(true)
或者HttpServletRequest.getSession()
getSession():如果当前已经创建了session则为这个用户则直接返回这个sesoin的对象。如果没有则创建一个新的。
HttpSession session = request.getSession();
session在下列情况下被删除:
A.程序调用HttpSession.invalidate() B.距离上一次收到客户端发送的session
id时间间隔超过了session的最大有效时间(tomcat服务器默认30分钟) C.服务器进程被停止
**注意:**关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。
超时限制
<session-config>
<session-timeout>30</session-timeout> <!-- 时长-->
</session-config>
WEB服务器采用“超时限制”的办法来判断客户端是否还在继续访问,如果某个客户端在一定的时间之内没有发出后续请求,WEB服务器则认为客户端已经停止了活动,结束与该客户端的会话并将与之对应的HttpSession对象变成垃圾。
如果客户端浏览器超时后再次发出访问请求,WEB服务器则认为这是一个新的会话的开始,将为之创建新的HttpSession对象和分配新的会话标识号。
HttpSession的生命周期
1、若当前的JSP(或Servlet)是客户端访问的当前WEB应用的第一个资源,且JSP的page指定的session属性为false,则服务器就不会为JSP创建一个HttpSession对象。
2、若当前JSP不是客户端访问的当前WEB应用的第一个资源,且其他页面已经创建一个HttpSession对象,则当前JSP页面会返回一个回话的HttpSession对象,而不是创建一个新的HttpSession对象。
3、对于Servlet而言:若Servlet是客户端的第一个WEB应用资源,则只有调用了request.getSession()或request.getSession(true)才会创建HttpSession对象。
重复提交
<body>
<%
String uuid = UUID.randomUUID().toString().replace("-", "");
request.getSession().setAttribute("token", uuid);
%>
<form action="loginServlet" method="get">
<input type="hidden" value="<%=uuid %>" name="token"> <!-- 隐藏域-->
<span>用户名:</span><input type="text" name="username" id="username"/><br>
<span>密 码:</span><input type="password" name="password" id="password"/><br>
<input type="submit" value="提交"/>
</form>
</body>
//Servlet
// 获取提交的用户名和密码
String name = request.getParameter("username");
String password = request.getParameter("password");
// 获取令牌
String token = request.getParameter("token");
// 获取session中的令牌
HttpSession session = request.getSession();
String sToken = (String) session.getAttribute("token");
if (token.equals(sToken)) {
System.out.println("重复提交");
session.removeAttribute("token");
} else {
System.out.println("重复提交");
}