Session
- 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
- Session和Cookie的主要区别在于:
- Cookie是把用户的数据写给用户的浏览器。
- Session技术把用户的数据写到用户独占的session中。
- Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。
购买Servlet:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//购买servlet
public class SessionDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
String sessionId = session.getId();
// 将回写给浏览器的Cookie覆盖,设置上有效期,那么这个session也就有有效期了
Cookie cookie = new Cookie("JSESSIONID", sessionId);
cookie.setPath("/day07");
// 设置有效期为30分钟
cookie.setMaxAge(60 * 30);
response.addCookie(cookie);
session.setAttribute("name", "洗衣机");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
结账Servlet:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//结账servelt
public class SessionDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-type", "text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String product = (String) session.getAttribute("name");
out.print("您购买的商品是:" + product);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
// 第一次执行getSession创建Session
// 关闭浏览器后sesson没死,三十分钟没人用才死
// session也是服务器中的web资源,session的配置要在web.xml中配置
/*
* 配置session60分钟没人用摧毁 <session-config> <session-timeout>60</session-timeout>
* </session-config>
*/
// 程序中摧毁session session.invalidate();
/*
* request.getSession(false);不创建session,只获取session,性能稍微高点,这个在购买的时候用,比如用户购买用的request
* .getSession();这个得到session
* 但是到购物车查看就不要重新创建session了,直接request.getSession(false);
* ,如果用request.getSession();的话,用户直接点购物车也会创建session
*/
// session是基于cookie的。服务器为浏览器创建的session的id,会通过cookie回写给浏览器,这个cookie是没有设置有效期的,浏览器一关就失效了
// 设置session的有效期,就是设置回写给浏览器的cookie的有效期。这个Cookie叫JSESSIONID
// 没有设置有效期的时候打开浏览器做一些session操作,然后重开一个浏览器 拿到的session是没有原来的操作的
// 没有设置有效期的session,也就是浏览器进程的session,在浏览器中新开选项卡和基于本浏览器打开新的浏览器是一个窗口(根据不同浏览器而言是不同的IE7打开两个窗口session的id是不同的,IE8打开两个窗口session的id就相同)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<a href="/day07/servlet/SessionDemo1">购买</a>
<a href="/day07/servlet/SessionDemo2">结账</a>
</body>
</html>
session实现原理
IE禁用Cookie后的session处理
- 实验演示禁用Cookie后servlet共享数据导致的问题。
- 解决方案:URL重写
- response. encodeRedirectURL(java.lang.String url)
用于对sendRedirect方法后的url地址进行重写。 - response. encodeURL(java.lang.String url)
用于对表单action和超链接的url地址进行重写
- response. encodeRedirectURL(java.lang.String url)
- 附加:
- Session的失效
- Web.xml文件配置session失效时间
session案例
1. 使用Session完成用户登陆
2. 利用Session防止表单重复提交
3. 利用Session实现一次性验证码
session防止表单重复提交
1.方法一
在前台处理:在浏览器端用JavaScript代码防止
<script type="text/javascript">
var isCommited = false;
function checkPost(){
if(!isCommited){
//document.getElementById("sub").disabled = true;
isCommited = true;
return true;
}else{
alert("不能重复提交");
return false;
}
}
</script>
2.方法二
在服务器端:用户提交表单,服务器端给提交的表单带唯一标识的随机数。
md5码
base64
- 表单页面由servlet程序生成,servlet为每次产生的表单页面分配一个唯一的随机标识号,并在FORM表单的一个隐藏字段中设置这个标识号,同时在当前用户的Session域中保存这个标识号。
- 当用户提交FORM表单时,负责处理表单提交的serlvet得到表单提交的标识号,并与session中存储的标识号比较,如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。
- 在下列情况下,服务器程序将拒绝用户提交的表单请求:
- 存储Session域中的表单标识号与表单提交的标识号不同
- 当前用户的Session中不存在表单标识号
- 用户提交的表单数据中没有标识号字段
- 编写工具类生成表单标识号:TokenProcessor
三个域对象的总结
在什么情况下使用什么容器?
使用request:
程序产生数据之后,显示完了就没用了,使用request。eg:你这个程序找servlet,servlet产生数据带给jsp,jsp显示完数据,数据就没用了。
使用session:
我这个程序除了产生数据,除了页面显示外,等一会儿还需要用到,这个时候需要session。例子1:图片文字校验,文字显示了,但是在服务器端还需要用到,需要去校验。例子2:用户登入,用户登入这个状态还需要用到。
使用ServletContent:
我这个程序产生了数据,不仅是给自己用,等会儿还要给别人用。例子:聊天室。
问题?:
服务器是如何做到一个session为一个浏览器的多次请求而服务
- 服务器创建session出来后,会把 session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session 的id号去,服务器发现客户机带session id过来了,就会使用内存中与之对应的session为之服务
如何做到一个session为多个浏览器服务
- 服务器第一次创建session,程序员把session id号,手工以cookie的形式回送给浏览器,并设置cookie的有效期这样,即使用户的浏览器关了,开新浏览器时,还会带着session id找服务器,服务器从而就可以用内存中与之对应的session为第二个浏览器窗口服务
如何做用户禁用cookie后,session还能为多次请求而服务
- 把用户可能点的每一个超链接后面,都跟上用户的session id号
session对象的创建和销毁时机
- 用户第一次request.getSession时
- session对象默认30分钟没有使用,则服务器会自动销毁session
- 用户在web.xml文件中手工配置session的失效时间
- 用户可以手工调用session.invalidate方法,摧毁session