Session
1、Cookie的局限:
1)Cookie只能存字符串类型。不能保存对象
2)只能存非中文。
3)1个Cookie的容量不超过4KB。
如果要保存非字符串,超过4kb内容,只能使用session技术!!!
2、Session特点:
会话数据保存在服务器端。(内存中)
3、Session的核心api
1)创建或得到session对象
HttpSession getSession()
HttpSession getSession(boolean create)
2)设置session对象
void setMaxInactiveInterval(int interval) : 设置session的有效时间
void invalidate() : 销毁session对象
java.lang.String getId() : 得到session编号
3)保存会话数据到session对象
void setAttribute(java.lang.String name, java.lang.Object value) : 保存数据
java.lang.Object getAttribute(java.lang.String name) : 获取数据
void removeAttribute(java.lang.String name) : 清除数据
服务器能够识别不同的浏览者!!!
一个简单的Session操作
/** * 将数据保存到session 中 */ public class SessionDemo extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1、得到session HttpSession session = request.getSession(); //保存会话 session.setAttribute("数据name", "数据值"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } } ============================================== ** * 从session域中得到数据 */ public class SessionDemo2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1、等到session域 HttpSession session = request.getSession(); //判断session域是否为空 if(session == null){ System.out.println("没有得到对应的session对象"); } //2、取出数据 String name = (String) session.getAttribute("数据name"); System.out.println("name"+":"+name); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
4、Session的原理
1、为什么服务器能识别不同的游览者??
前提: 在哪个session域对象保存数据,就必须从哪个域对象取出!!!!
浏览器1:(给s1分配一个唯一的标记:s001,把s001发送给浏览器)
1)创建session对象,保存会话数据
HttpSession session = request.getSession(); --保存会话数据 s1
浏览器1 的新窗口(带着s001的标记到服务器查询,s001->s1,返回s1)
1)得到session对象的会话数据
HttpSession session = request.getSession(); --可以取出 s1
新的浏览器1:(没有带s001,不能返回s1)
1)得到session对象的会话数据
HttpSession session = request.getSession(); --不可以取出 s2
浏览器2:(没有带s001,不能返回s1)
1)得到session对象的会话数据
HttpSession session = request.getSession(); --不可以取出 s3
/** * 将数据保存到session 中 */ public class SessionDemo extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1、得到session HttpSession session = request.getSession(); //得到session id --> JSESSIONID String id =session.getId(); System.out.println("id:"+id); //保存会话 session.setAttribute("数据name", "数据值"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } } ============================================== /** * 从session域中得到数据 */ public class SessionDemo2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1、等到session域 HttpSession session = request.getSession(); //判断session域是否为空 if(session == null){ System.out.println("没有得到对应的session对象"); } //得到session id -->JSESSIONID,如果相同,就证明是同一个session域 String id = session.getId(); System.out.println("id:"+id); //2、取出数据 String name = (String) session.getAttribute("数据name"); System.out.println("name"+":"+name); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
代码解读:HttpSession session = request.getSession();
1)第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID
new HttpSession();
2)把JSESSIONID作为Cookie的值发送给浏览器保存
Cookie cookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie);
3)第二次访问的时候,浏览器带着JSESSIONID的cookie访问服务器
4)服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象。
if(找到){
return map.get(sessionID);
}
Map<String,HttpSession>]
<"s001", s1>
<"s001,"s2>
5)如果找到对应编号的session对象,直接返回该对象
6)如果找不到对应编号的session对象,创建新的session对象,继续走1的流程
结论:通过JSESSION的cookie值在服务器找session对象!!!!!
5、Session细节问题
1)java.lang.String getId() : 得到session编号
2)两个getSession方法:
getSession(true) / getSession() : 创建或得到session对象。没有匹配的session编号,自动创建新的session对象。
getSession(false): 得到session对象。没有匹配的session编号,返回null
3)void setMaxInactiveInterval(int interval) : 设置session的有效时间
session对象销毁时间:
3.1 默认情况30分服务器自动回收(不设置的话30分钟销毁)
3.2 修改session回收时间
3.3 全局修改session有效时间.在web.xml中使用<session-config>标签 ,但是是分钟
<!-- 修改session全局有效时间:分钟 --> <!-- <session-config> <session-timeout>1</session-timeout> //表示session保存1分钟 </session-config> -->
3.4.手动销毁session对象
void invalidate() : 销毁session对象
4)如何避免浏览器的JSESSIONID的cookie随着浏览器关闭而丢失的问题
/** * 手动发送一个硬盘保存的cookie给浏览器 */ Cookie c = new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c); |
/** * 保存会话数据到session域对象 * * */ public class SessionDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.创建session对象 HttpSession session = request.getSession(); /** * 得到session编号 */ System.out.println("id="+session.getId()); /** * 修改session的有效时间 */ //session.setMaxInactiveInterval(20); /** * 手动发送一个硬盘保存的cookie给浏览器 */ Cookie c = new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c); //2.保存会话数据 session.setAttribute("name", "rose"); } } ============================================= /** * 从session域对象中取出会话数据 * * */ public class SessionDemo2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.得到session对象 HttpSession session = request.getSession(false); if(session==null){ System.out.println("没有找到对应的sessino对象"); return; } /** * 得到session编号 */ System.out.println("id="+session.getId()); //2.取出数据 String name = (String)session.getAttribute("name"); System.out.println("name="+name); } }
/** * 销毁session对象 * * */ public class DeleteSession extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(false); if(session!=null){ session.invalidate();//手动销毁 } System.out.println("销毁成功"); } }