会话技术 – Cookie与Session及其两者的区别
(一)会话技术
一、概述
1. 一个浏览器为了实现某一个功能对服务器产生了多次请求响应。从第一个请求开始访问服务器,会话开始,到最后一个页面访问结束 关闭所有页面,这个过程中的所有的请求响应加在一起称之为 浏览器和服务器之间产生了一次会话。
2. 会话技术最重要的是会话中产生的数据如何保存 。
1. request域 – 不合适。request太小了,每一次请求都会产生一个新的request , 后续的请求无法读取到之前请求的request中存放的数据 。
2. servletContext – 不合适。 所有的会话看到的都是同一个ServletContext域 , 所有会话的数据会混杂在一起
3. cookie – 将会话产生的数据存放在客户端
4. session – 将会话产生的数据保存在服务器中
(二)Cookie
一、概述
- Cookie是客户端技术 将会话产生的数据保存在客户端中
- 当浏览器访问服务器 服务器可以通过在响应中增加set-Cookie的响应头 命令浏览器保存一段cookie信息
- 浏览器会将cookie信息保存在本地 之后再去访问服务器时 会自动在请求中 通过cookie请求头 带着cookie信息
- 服务器可以通过解析请求中的cookie请求头 获取信息 从而获取到了之前保存的会话相关的数据
二、基本方法
- Cookie(String name ,String value) :cookie没有无参构造方法 , 在创建时就得制定好cookie的名字和值 。
- getName() : cookie的名字只能获取不能修改
- getValue(String name) : 通过名字获取对应的值
- setValue(String name , String value) : 通过名字设置对应的值 。
- response.setCookie(Cookie c): 向响应中添加cookie
- request.getCookies() : 从请求中获取所有的cookie
三、cookie保存时长
- 如果不设置cookie保存时长 , 默认cookie会保存在浏览器内存中 , 浏览器关时cookie销毁 , 这种称之为会话级别的cookie 。
可以通过代码制定浏览器将cookie保存到什么时候 , 浏览器收到的 cookie信息中如果包含了cookie超时时间 , 浏览器就会把cookie信息以文件的形式保存在浏览器的临时文件夹中 , 保存到指定的时间 , 这段时间内cookie文件一直存在 , 即使对此开关 浏览器仍然能够读取到这个cookie信息。
设置超时时间 setMaxAge(int time);//单位是秒 获取超时时间 getMaxAge()
四、浏览器访问哪些路径时会携带cookie
- 如果不设置 , 默认在访问发送cookie给浏览器的servlet的父一级目录及子孙目录时会携带这个cookie 。
可以通过代码设置浏览器在访问哪些路径时携带这个cookie
设置路径 setPath(String path); 获取携带这个cookie的路径 getPath();
五、删除cookie
- java提供的Cookie类中本身没有删除一个cookie的方法 , 但是可以通过一些方法实现删除cookie的效果 。
- 如果想要删除一个cookie , 需要发送一个和要删除的cookie名字相同 , path相同 , 但是maxAge为0的cookie 。
- 原理: 当发送一个与原cookie名字相同 , path也相同的cookie时 , 原cookie将会被覆盖 , 但是新cookie的maxAge为0 , 即刚被创建就被删除 , 从而实现了删除一个cookie 。
六、Cookie其他
- 一个Cookie只能标示一种信息 , 他至少含有一个标识信息的名字(name)和设置值(value)。
- 一个WEB站点可以给一个web浏览器发送多个cookie , 一个web浏览器也可以存储多个web站点提供的cookie 。
- 浏览器一般只允许存放300个cookie, 且 每个站点最多 能存放20个从cookie , 每个cookie的大小被限制在4KB以内 。
- 如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
- 注意:浏览器是通过name+path来唯一标示一个cookie的 。 在删除一个cookie时name和path必须一致 , value可以随意设置 。
八、案例
- 登录时记住用户名和密码 。
(三)Session
一、Session概述
- session时服务器端会话保存技术
- 服务器在需要时 , 可以为每个用户创建一个独一无二的为该用户服务的session对象 , 其中保存着该用户会话相关的数据 。
- 之后该用户再来访问服务器时 , 可以找到志强创建的属于他的session , 从中找到之前 保存的数据 。 从而实现会话数据的保存 。
- 由于每个用户各自有各自的session , 每一个session只为对应的用户服务 , 所以数据不会产生混乱 。
二、session是一个域对象
- 生命周期:
- 当第一次调用request。getSession()方法时表明会话中需要硬session来服务了, 此时服务器会创建一个session对象 , 一直驻留在内存中为当前会话服务 。
- session有三种销毁方式:
- 自杀: 可以通过明确调用session.invalidate()方法立即杀死当前session 。
- 寿终正寝 : session默认发呆时间为30分钟 , 如果超过30分钟没有用户使用这个session , 则服务器会认为这个session超时 , 杀死会话对应的session 。
- 意外身亡 : 当web应用销毁时 , session也随之销毁 。
- 作用范围: 整个会话
- 主要功能: 在会话范围内共享数据
三、常用方法
创建、获取session
获取一个session对象 , 如果当前 会话已经有session对象 , 则直接获取 , 如果没有则创建 request.getSession(); 当传入的值为true时 , 与上面的方法相同 ; 如果传入的参数为false时 , 当前会话存在session时直接获取 , 不存在时返回null request.getSession(boolean b);
操作域
//设置session数据 session.setAttribute(); //获取session数据 session.getAttribute(); //移除session数据 session.removeAttribute();
杀死session
session.invalidate()
四、案例
- 利用session实现登录 、 注销
- 登录
- 所谓的登录其实就是用户提交用户名和密码 后检查数据库
- 如果不正确就跳转回登录界面并提示用户重新输入
- 如果正确则创建 session保存该用户的登录标记
- 在之后的访问中可以通过 检查登录 标记货值该用户 是否登录 , 如果登录过 ,该用户是谁 。
- 注销
- 所谓的注销其实就是杀死session,使session中的登录标记失效 。
- 登录
- 验证码校验
- 验证码图片生成之后将图片发送至页面 , 并且将验证码中的内容存入session中备用
- 用户提交参数后 ,从请求中获取验证码参数 , 再从session中获取验证码 元数据 , 两者比对
- 如果验证码不通过返回注册页面 数据回显
- 数据回显
- 数据在发送前被存放在request域中在进行发送
- 如果后台校验不通过 , 则请求转发回注册页面
- 此时request还是发送请求时的那个request , 直接从中取相应的值就行 。
五、session原理
- 实际上session是基于一个叫做jsessionid的 cookie工作的 。
- 当浏览器访问服务器调用到request.getSession()时 , 此方法会检查请求中是否有叫做jsessionid的cookie 。如果没有 , 则说明这是第一次用到session , 此时服务器会自动创建一个session使用 , 并将sessionid作为name为jsessionid的cookie的值发送给浏览器保存 。浏览器在后续的访问中 , 就会带着 这个jsessionid来访问 , 后续再调用到request.getSession()时, 此方法会检查请求中是否有叫做jsessionid的cookie , 如果有则在浏览器内存中找jsessionid对应的session使用 。 如果找不到 , 说明session已经被销毁 ,则创建一个新的session使用 , 并在响应中发送新的jsessionid 。
六、cookie被禁用后session无法被使用的情况
- 如果禁用了cookie session也就用不了了 - 可以通过URL重写来解决
- 如果禁用了cookie 浏览器不再基于cookie来保存jsessionid 在服务器无法获取到jsessionid 也就无法找对应的session
- 所以想解决这个问题 就需要想办法 将jsessionid的值 带给服务器。此时可以使用URL重写的技术来实现
URL重写
- 所谓的URL的重写 就是 将地址 改写 在地址后使用特殊的参数 携带jsessionid的技术 。
- 虽然cookie用不了了 但是 通过地址 仍然可以携带jsessionid的信息 从而使用session
- 这个技术 需要将应用中所有的地址都要进行URL重写 相对来说非常麻烦
- 而这么麻烦带来的唯一的好处是 禁用cookie后仍然可以使用session 似乎并不值得这么麻烦
- 所以 现在很多网站 都不会去做URL重写 对于禁用cookie的情况 不处理 或者 检测到用过户禁用cookie就引导用户 打开浏览器的cookie 再来使用网站
示例:
response.encodeURL(String url); //--如果是普通的地址用这个方法 response.encodeRedirectURL(String url); //--如果地址是用来进行重定向的,用这个方法
(四)Cookie与session的区别
- cookie将会话相关数据保存在客户端 ; session将会话相关的数据保存在服务器端
- cookie可以保存的时间比较长; session超过30分种没人用就销毁
- cookie有可能随着用户的操作被清除 ;session只要不手动删除 在存活期间可以可靠的访问
- cookie将信息保存在浏览器中 可以通过翻临时文件夹 查看cookie中的数据 不安全; session将会话相关的数据保存在服务器内存中 安全性高很高。
- 如果需要将会话数据保存的很久 – cookie
- 如果希望会话数据不会因为用户的操作丢失 – session
- 如果会话数据比较在意安全性 – session