1. Session简介
Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
1.1 Session的生命周期
Session的创建:
在一个会话中,当浏览器首次访问Servlet,并且该Servlet中有request.getSession()语句时才会创建一个Session对象。
Session的摧毁:
1)服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为30分钟(可以在web.xml中配置<session-config>标签来设定失效时间)。
2)调用Session的invalidate方法时会摧毁Session对象
1.2 Session和Cookie比较
Cookie是把用户的数据写给用户的浏览器;Session技术把用户的数据写到用户独占的session中。
1.3 Session演示:
假如在一个购物网站上,有一个主页,有一个购买按钮,有一个结账按钮:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>网站首页</title>
</head>
<body>
<a href="/day07/SessionDemo">购买</a>
<a href="/day07/SessionDemo2">结账</a>
</body>
</html>
SessionDemo:
package com.oner.session;
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;
//购买Servlet
public class SessionDemo extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
session.setAttribute("name", "洗衣机");
out.print("购买成功,请结账!");
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
SessionDemo2:
package com.oner.session;
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;
//支付Servlet
public class SessionDemo2 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String product = (String) session.getAttribute("name");
out.print("您购买的商品是:" + product+"<br/>结账成功!");
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
在浏览器地址栏中输入:http://localhost:8080/day07/index.html,回车:
点击“购买”,网页自动跳转到了SessionDemo页面,显示“购买成功,请结账!”:
返回主页,点击“结账”,网页自动跳转到了SessionDemo2页面,显示“您购买的商品是:洗衣机,结账成功!”:
从上面可以看出Session的基本工作过程,其实就是在用户访问SessionDemo页面时,服务器为这个用户创建一个Session对象,里面存放在这个用户的一些数据(在这里是购买了洗衣机),,当用户进入SeesionDemo2页面时,再从Seesion对象中拿到这个用户的数据(购买了洗衣机)。
是设想这样一种场景:有用户A和用户B同时访问购买页面,且购买的商品不同,然后又同时访问支付页面,服务器如何判断哪个Seesion对象中存放的是用户A的数据,哪个存放的是用户B的数据呢?
其实Session是基于Cookie实现的,如果在点击购买按钮时打开httpwatch,会发现如下信息:
在相应信息的响应头中发现Set-Cookie为:JSESSIONID=1A3AFFD9F1A0E53534823F71F5A3BCB2; Path=/day07。说明当用户的一些数据存储在Session对象后,服务器也会为将该Session对象的id信息以Cookie的形式发送给浏览器。
当点击结账按钮时,查看httpwatch:
发现在响应头中Cookie的值为JSESSIONID=1A3AFFD9F1A0E53534823F71F5A3BCB2,说明在用户点击结账按钮时,同时会将为他服务的Session对象的id发送给服务器。服务器收到请求后,会先匹配id是否一致,如果一致则继续为其服务。
明白了上面的原理,这里再做一个实验,先进入主页,点击购买按钮:
然后重启浏览器,进入主页后,点击结账按钮:
发现显示购买的商品是:null。这是怎么回事呢?其实这时以为如果没有JSESSIONID这个Cookie的默认时效是本次会话,如果中途关闭浏览器,这个JSESSIONID就失效了。可以自己手动设定下JSESSIONID的时效。现在修改下SessionDemo:
package com.oner.session;
import java.io.IOException;
import java.io.PrintWriter;
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 SessionDemo extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
session.setAttribute("name", "洗衣机");
out.print("购买成功,请结账!");
String sessionId= session.getId();
Cookie cookie=ne