Servlet 会话技术cookie和session
会话技术
Cookie技术:会话数据保存在浏览器客户端。
Session技术:会话数据保存在服务器端。
一、Cooke技术
1、 特点
Cookie技术:会话数据保存在浏览器客户端。
2 、Cookie技术核心
Cookie类:用于存储会话数据
1)构造Cookie对象
Cookie(java.lang.String name, java.lang.String value)
2)设置cookie
void setPath(java.lang.String uri) :设置cookie的有效访问路径
void setMaxAge(int expiry) : 设置cookie的有效时间
void setValue(java.lang.String newValue) :设置cookie的值
3)发送cookie到浏览器端保存(两种方式:自动发送(推荐)和人工发送)
void response.addCookie(Cookie cookie) : 发送cookie ----自动
response.setHeader("set-cookie", cookie.getName()+"="+cookie.getValue()); ----人工
4)服务器接收cookie
Cookie[] request.getCookies() : 接收cookie
3、Cookie原理
1)服务器创建cookie对象,把会话数据存储到cookie对象中。
new Cookie("name","value");
2) 服务器发送cookie信息到浏览器
response.addCookie(cookie);
举例: set-cookie: name=eric (隐藏发送了一个set-cookie名称的响应头)
3)浏览器得到服务器发送的cookie,然后保存在浏览器端。
4)浏览器在下次访问服务器时,会带着cookie信息
举例: cookie: name=eric (隐藏带着一个叫cookie名称的请求头)
5)服务器接收到浏览器带来的cookie信息
request.getCookies();
示意图:
4、 Cookie的细节
1)void setPath(java.lang.String uri) :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。
2)void setMaxAge(int expiry) : 设置cookie的有效时间。
正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。
负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!(浏览器默认)
零:表示删除同名的cookie数据
3)Cookie数据类型只能保存非中文字符串类型的。可以保存多个cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
1、采用人工发送,浏览器关闭时,cookie死亡。
1 package com.uplooking.controller; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.annotation.WebServlet; 6 import javax.servlet.http.Cookie; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 @WebServlet("/CookieAction") 12 public class CookieAction extends HttpServlet { 13 private static final long serialVersionUID = 1L; 14 public CookieAction() { 15 super(); 16 } 17 18 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 19 //1、创建一个cookie 以key-value的形式存储 20 Cookie cookie=new Cookie("name","laowang"); 21 //2、人工发送 设置响应头 22 response.setHeader("set-cookie", cookie.getName()+"="+cookie.getValue()); 23 24 } 25 }
从浏览器键入URL:http://localhost:8081/20180912/CookieAction
执行结果:
第二次请求URL:http://localhost:8081/20180912/CookieAction
执行结果:内存中已经含有上次登录的cookie信息
2、采用人工发送,设置时效长度。时效结束后Cookie死亡。
1 package com.uplooking.controller; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.annotation.WebServlet; 6 import javax.servlet.http.Cookie; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 12 @WebServlet("/CookieAction") 13 public class CookieAction extends HttpServlet { 14 private static final long serialVersionUID = 1L; 15 16 public CookieAction() { 17 super(); 18 19 } 20 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 21 /** 22 设置cookie 23 void setPath(java.lang.String uri) :设置cookie的有效访问路径 24 void setMaxAge(int expiry) : 设置cookie的有效时间 25 void setValue(java.lang.String newValue) :设置cookie的值 26 setMaxAge 正数 存活时间以秒为单位 27 0 删除 28 负数 时效一次 关闭浏览器死亡(默认) 29 */ 30 //1、创建一个cookie 以key-value的形式存储 31 Cookie cookie=new Cookie("age","666"); 32 33 //2、设置时效 3600s一个小时 34 cookie.setMaxAge(60*60); 35 36 //3、自动发送 推荐使用 37 response.addCookie(cookie); 38 39 } 40 }
从浏览器键入URL:http://localhost:8081/20180912/CookieAction
执行结果:
获取cookie数组
1 package com.uplooking.controller; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.annotation.WebServlet; 6 import javax.servlet.http.Cookie; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 @WebServlet("/GetCookieAction") 12 public class GetCookieAction extends HttpServlet { 13 private static final long serialVersionUID = 1L; 14 15 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 16 Cookie[] cookies=request.getCookies(); 17 if(cookies!=null) { 18 for(Cookie cookie:cookies) { 19 System.out.println(cookie.getName()+" "+cookie.getValue()); 20 } 21 } 22 } 23 }
从浏览器键入URL:http://localhost:8081/20180912/GetCookieAction
执行结果:
关于Cookie中文乱码问题的解决
二、Session技术
1 、引入
Cookie的局限:
1)Cookie只能存字符串类型。不能保存对象
2)只能存非中文。
3)1个Cookie的容量不超过4KB。
如果要保存非字符串,超过4kb内容,只能使用session技术!!!
Session特点:
会话数据保存在服务器端。(内存中)
2、Session技术核心
HttpSession类:用于保存会话数据
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) : 清除数据
3、Session原理
问题:服务器能够识别不同的浏览者!!!
现象:
前提: 在哪个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(); --不可以取出 s
代码解读: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对象!!!!!
Session示意图:
4、Sesson细节
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分服务器自动回收
3.2 修改session回收时间
3.3 全局修改session有效时间
<!-- 修改session全局有效时间:分钟 --> <session-config> <session-timeout>1</session-timeout> </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); |
总结:
1)会话管理: 浏览器和服务器会话过程中的产生的会话数据的管理。
2)Cookie技术:
new Cookie("name","value")
response.addCookie(coookie)
request.getCookies()
3)Session技术
request.getSession();
setAttrbute("name","会话数据");
getAttribute("会话数据")
package com.uplooking.controller; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @WebServlet("/SessionAction") public class SessionAction extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //创建session对象,保存会话数据 HttpSession session=request.getSession(); session.setAttribute("123", "321"); request.getRequestDispatcher("/GetCookieAction").forward(request,response); } }
从浏览器键入URL:http://localhost:8081/20180912/SessionAction
执行结果:
从浏览器键入URL:http://localhost:8081/20180912/
执行结果:
获取JESSIONID:
1 package com.uplooking.controller; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.annotation.WebServlet; 6 import javax.servlet.http.Cookie; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 @WebServlet("/GetCookieAction") 12 public class GetCookieAction extends HttpServlet { 13 private static final long serialVersionUID = 1L; 14 15 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 16 Cookie[] cookies=request.getCookies(); 17 if(cookies!=null) { 18 for(Cookie cookie:cookies) { 19 System.out.println(cookie.getName()+" "+cookie.getValue()); 20 } 21 } 22 } 23 }
从浏览器键入URL:http://localhost:8081/20180912/GetSessionAction
执行结果:
后台执行结果:
例:记录上一次登陆时间
1 package com.uplooking.controller; 2 3 import java.io.IOException; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.annotation.WebServlet; 9 import javax.servlet.http.Cookie; 10 import javax.servlet.http.HttpServlet; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 @WebServlet("/LastLoginAction") 15 public class LastLoginAction extends HttpServlet { 16 private static final long serialVersionUID = 1L; 17 private SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 18 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 19 //当前时间 20 String newTime=sdf.format(new Date()); 21 //上一次登陆时间 22 String lastTime=null; 23 //设置文本格式,否则会乱码 24 response.setContentType("text/html;charset=utf-8"); 25 26 //获取Cookie 27 Cookie[] cookies=request.getCookies(); 28 29 //在cookie有效时间内登陆 30 if(cookies!=null) { 31 for(Cookie cookie:cookies) { 32 if("lastLogin".equals(cookie.getName())) { 33 //获取上一次登陆的时间 34 lastTime=cookie.getValue(); 35 //设置新的登陆时间 36 cookie.setValue(newTime); 37 response.getWriter().write("上一次浏览的时间"+lastTime); 38 //将cookie加回去,回传给客户 39 response.addCookie(cookie); 40 //只用一个,停止循环 41 break; 42 } 43 } 44 } 45 //若是第一进来,则创建cookie,需要把cookie和时间加进去 46 if(cookies==null||lastTime==null) { 47 //将本次的登陆时间,赋给最后一次的时间记录点 48 // 参数:cookie的name,value 49 Cookie cookie=new Cookie("lastLogin",newTime); 50 response.getWriter().write("第一次登陆时间:"+newTime); 51 response.addCookie(cookie); 52 } 53 } 54 }
从浏览器键入URL:http://localhost:8081/20180912/GetSessionAction
执行结果: