Java之Session&Cookie
1、会话管理
1.1 什么是会话管理?
将浏览器与Web服务器之间多次交互(一次请求与响应)当做一个整体来处理,并且将多次交互所产生的数据(即状态)保存下来。
1.2 为什么使用会话管理?
客户端和服务器之间进行数据通讯遵循的是HTTP协议,而此协议属于无状态协议(一次请求对应一次响应,响应完则断开连接),服务器是无法跟踪客户端请求的,但是某些具体的业务是需要服务器能够识别客户端的,,会话管理相关知识就是解决此问题。
1.3 如何进行状态/会话管理?
- a)方式一:将状态保存在浏览器端(客户端)
- 通常使用Cookie技术
- b)方式二:将状态保存在服务器端
- 通常使用Session技术
通过Cookie技术可以让服务器给客户端添加一个标示, 响应完之后,客户端之后每次发请求都会带着这个标示,从而能够让服务器识别此客户端,,但是这种方案数据是保存在客户端的,存在被篡改的风险。而Session的出现就是为了安全性的问题, 因为使用Session数据是保存在服务器端,不存在被篡改的可能,但是关闭浏览器session中的所有数据都会被清除。
2、Cookie
2.1 什么是Cookie?
服务器临时存放在浏览器端的少量数据(最大4KB),用于跟踪用户的状态
当浏览器访问服务器时,服务器会将少量数据以set-cookie消息
头的方式发送给浏览器,浏览器会将这些数据保存下来。
当浏览器再次访问服务器时,会捋这些数据以 cookie消息头的方式发送给服务器
2.2 Cookie运作流程
2.3 如何使用Cookie?
//添加Cookie
Cookie c = new Cookie(String name, String value);
//设置Cookie在客户端存储的时长
c.setMaxAge(60*60*24*30*12*10);//十年之期,后面详细介绍
// 将Cookie下发给客户端浏览器
response.addCookie(c);
2.4 如何使用Cookie?
在servlet中使用Cookie
//获取所有的Cookie
Cookie[] cookies = request.getCookies();//注意:这个方法有可能取出null值
if(cookies != null) {
//遍历
for (Cookie cookie : cookies) {
String name = cookie.getName();
if("username".equals(name)) {
//找到了,显示该cookie的值
out.println(cookie.getValue());
//获取到的value可以放在页面……
}
}
在Vue框架中使用Cookie
//得到Cookie里面保存的用户名和密码 ,并显示到页面中
let cookie = document.cookie;
//cookie保存形式:username=admin;password=123456
let cookieArr = cookie.split(";");
//for of 相当于java中的foreach
for (let c of cookieArr) {
let arr = c.split("=");
let key = arr[0].trim();
let value = arr[1];
/*
判断出用户名和密码把值给到VUE中的变量,由于页面内容和此变量进行了双向绑定
页面会自动发生改变
*/
if (key == "username") {//为什么不使用equals比较,因为这是JavaScript的代码,可以直接用==来判断
v.username = value;
}
if (key == "password") {
v.password = value;
}
}
2.5 Cookie的生存时间
- 默认情况下,浏览器会将cookie保存在内存中,浏览器只要关闭,cookie就会被删除。
- 但可以调用setMaxAge方法来设置cookie的生存时间
cookie.setMaxAge(int seconds); 注: 1、seconds单位为秒 2、当seconds>0,浏览器会将cookie保存在硬盘上,到超过设定的事件,浏览器会将cookie删除 3、当seconds<0,浏览器会将cookie保存在内存当中 4、当seconds=0,删除cookie 比如,要删除一个名称为username的cookie,代码如下: Cookie c = new Cookie("username",""); c.setMaxAge(0); response.addCookie(c);
2.6 Cookie的编码问题(了解)
- 什么是cookie的编码问题?
Cookie只能存放合法的ASCII字符,如果要存放中文,需要将中文转换成合法的ASCII字符的形式。
- 如何处理这个问题?
在实际开发中,对添加成为cookie的数据统一使用encode方法来编码,然后使用时进行decode解码
具体使用//存入中文时编码 String URLEncoder.encode(String str, String charset);//这个方法会将中文根据编码转换成%开头的16进制数,这段16进制数是合法的ASCII字符 //取出时解码 String URLEncoder.decode(String str, String charset);//将%开头的16进制数根据编码转成原来的数据
String city = URLEncoder.encode("北京","utf-8");//转成加上%的16进制,如下图 Cookie c = new Cookie("city",city); response.addCookie(c);
//servlet,读取浏览器发送过来的cookie Cookie[] cookies = request.getCookies(); if(cookies != null) { for (Cookie cookie : cookies) { String name = cookie.getName(); String value = URLDecoder.decode(cookie.getValue(),"utf-8"); out.println(name+":"+value+"<br/>"); } }else { out.println("没有Cookie"); }
2.7 Cookie的路径问题(了解)
-
什么是Cookie的路径问题?
当浏览器访问服务器时,会比较请求地址是否与cookie的路径匹配,只有匹配的cookie才会被发送
如下:
在哪里添加的cookie,那个cookie就会存在哪个文件夹下。我在webapp>biz01下使用的addCookie.jsp创建了一个cookie,那么这个cookie会被存放在哪呢?
-
cookie的默认路径
cookie的默认路径等于添加改cookie的web组件到的路径,比如AddCookieServlet(/day06/addCookie)添加了一个cookie,
则该cookie的默认路径是“/day06”
举个实际例子
例如在day06包下创建一个biz01文件夹,文件夹下新建一个addCookie.jsp
部署运行addCookie.jsp后的浏览器中这个添加的cookie信息如下
-
cookie路径的匹配规则
请求地址要么是等于cookie的路径,要么是cookie的子路径,只有符合该条件的cookie,浏览器才会发出去
-
修改cookie路径
cookie.setPath(String path);
在添加cookie的时候使用
注:path就是路径
2.8 Cookie的限制
- cookie可以被用户禁止
- cookie不安全(对于敏感数据,一定要加密)
- cookie只能保存少量数据(大约4k左右)
- cookie的数量也有限制(大约是几百个)
- cookie只能保存字符串
3、Session
3.1 session是什么?
服务端为了保存状态而创建的一个特殊的对象
当浏览器访问服务器时,服务器端创建一个特殊的对象(该对象一般称之为 session对象,该对象有一个唯一的id,一般称之为 sessionId)。服务器会将session以 cookie的方式发送给浏览器。当浏览器再次访问服务器时,会将 sessionId发送过来,服务器端可以依据 sessionId找到对应的 session对象。
3.2 如何获取session对象?
Httpsession s = request getsession(boolean flag);
注:
a. Httpsession是一个接口。
b. 如果fag为true:先查看请求当中是否有 sessionid,如果没有,则创建一个 session对象;如果有 sessionId则依据 sessionid查找对应的 session对象,如果找到了,则返回该对象,找不到,则创建一个新的session对象。
c. 如果flag为false:先查看请求当中是否有 sessionid,如果没有,返回null;如果有 sessionid,则依据 sessionid查找对应的 session对象,如果找到了,则返回该对象,找不到,返回null。
3.3 session对象的常用方法
-
a)
session.setAttribute(String name, object obj);
绑定数据,以name作为key,以obj作为vaue,将数据存放到了
一个Map对象里面。 -
b)
Object session.getAttribute(String name);
依据绑定名获取绑定值,如果绑定值不存在则返回null -
c)
session.removeAttribute(String name);
解除绑定
3.4 session超时
-
什么是session超时?
服务器会将空闲时间过长的 session对象删除掉。
注:缺省的超时时间长度一般是30分钟。 -
如何修改超时时间长度?(一般来说不用改)
方式一:
修改web.xml配置文件,(注意这个配置文件一旦修改,所有部署到这个服务器上的项目都会受到影响),如果不想这样可以找到一个单独项目的web.xml文件将添加进去就可以了,这样只有这个项目的session会受影响
方式二:
session.setMaxInactiveInterval(int seconds)
设置两次请求之间的最大间隔时间,如果超过了该时间,则session对象会被删除
3.5 删除session
session.invalidate();
作用是将session设置为失效,一般在退出效果时使用
会话失效有2种情况:会话超时和主动杀会话
一般在做退出效果时候,推荐主动杀死会话,如果退出时不清会话,用户点击浏览器后退,依然无需登录可以正常访问站点。
4、Cookie和Session的区别
-
Cookie:类似于打孔式的会员卡, 数据保存在客户端
- 保存时间: 默认保存在浏览器的内存中, 会话结束时浏览器会清除掉, 可以修改成任意时间,如果修改了保存时间,数据会保存到磁盘中,时间到了之后才会清除.
- 使用Cookie只能保存字符串类型的数据
- 应用场景:记住用户名和密码
-
Session: 类似于银行卡, id保存在客户端, 数据保存在服务器
- 保存时间: 数据是保存在服务器的内存中,默认保存半个小时左右时间, 而且重启程序或关闭程序都会清除.
- Session可以保存任意对象类型的数据.
- 应用场景:记住登录状态
-
Session相对于Cookie优点是
- 更安全,因为session把数据保存在服务器端
- 可以保存更多的数据
- 支持更丰富的数据类型
- 缺点是需要占用服务器端的内存空间