JavaWeb:会话Cookie与Session
JavaWebDay04
会话
从访问服务器到访问结束,是一次会话的多次请求和响应
会话开始 | 会话过程 | 会话结束 |
---|---|---|
第一次访问服务器 | 期间多次访问 | 浏览器关闭 |
会话作用:
保存会话过程产生数据
由于HTTP的无状态特性,没有记忆功能,所以需要会话技术
类型 | 概述 |
---|---|
Cookie | 客户端会话技术:数据保存再客户端 |
Session | 服务器端会话技术:数据保存再服务器端 |
Cookie
保存在浏览器端的小文件
用于保存服务器传过来的数据
Cookie类的方法 | 作用 |
---|---|
Cookie(String name,String value) |
创建一个Cookie |
String getName() |
获取键 |
String getValue() |
获取值 |
response.addCookie(Cookie cookie):
把Cookie传给浏览器
Cookies[] request.getCookies()
读取浏览器传过来的Cookie
Cookie运行原理
Cookie技术的运行原理
1.浏览器一次访问服务器时没有Cookie数据
2.服务器创建Cookie对象封装数据并以响应头的形式返回给浏览器
3.浏览器将接收到的Cookie保存在本地的文件中
4.浏览器再次访问服务器时会将本地Cookie数据以请求头的形式携带给服务器
5.服务器读取浏览器发送的Cookie
Cookie过期时间
默认:浏览器关闭即过期
但可以设置过期时间:
void setMaxAge(int expiry)
expiry 大于 0:正确设置过期时间
expiry 小于 0:无效,相当于默认
expiry 等于 0:删除Cookie
设置Cookie的有效路径
Cookie设置路径的方法 | 功能 |
---|---|
cookie.setPath(路径) |
用于设置Cookie访问的路径 访问这个路径或路径的子路径都可以访问Cookie,其它的路径无法访问, 换言之,只有这个路径或它的子路径,浏览器才会将Cookie的信息发送给服务器 默认路径:当前的项目访问路径 |
Cookie中使用非法字符
注:Tomcat8可以包含中文了
URL编码与解码相关方法 | 说明 |
---|---|
java.net.URLEncoder.encode("字符串","utf-8") |
使用指定的码表对字符串进行编码 |
java.net.URLDecoder.decode("字符串","utf-8") |
使用指定的码表对字符串进行解码 |
如何在Cookie中包含非法字符
1.先对包含非法字符的字符串进行URL编码
2.将编码后的结果作为Cookie的值返回给浏览器
3.服务器读取到Cookie值时需要进行URL解码才能还原数据
删除Cookie
如何删除浏览器端的Cookie信息
1.创建一个同名的Cookie对象:有效路径要一致,值无所谓
2.设置过期时间为0
3.返回给浏览器即可
Session
Session是什么:
是服务器内部的一小块内存区域,底层是Map结构
每个会话都会有自己的内存区域,不同会话之间数据不共享
Session的作用:
用来保存会话过程中产生的数据:可以在同一个会话中多个Servlet之间共享
相关方法 | 功能 |
---|---|
request.getSession() |
获取会话域对象 |
setAttribute(String name,String value) |
存储键值对数据 |
session技术运行原理
1.浏览器第一次访问没有会话ID
2.服务器第一次调用请求对象的
getSession
方法时,服务器会为该会话分配一小块内存区域并指定一个会话ID3.服务器将这个会话ID以Cookie的形式交给浏览器
4.浏览器将这个会话ID保存在本地文件中
5.当下次访问时就可以使用这个会话ID以请求头的形式交给服务器
6.服务器再根据这个唯一标识获取数据
session常用方法演示
HttpSession 接口方法 |
作用 |
---|---|
String getId() |
获得会话ID |
long getCreationTime() |
获得会话创建时间:毫秒值 |
long getLastAccessedTime() |
获得上一次访问会话域的时间:毫秒值 |
boolean isNew() |
判断是否是新的会话 |
ServletContext getServletContext() |
获得上下文对象 |
session常见问题
1.浏览器关闭后,还能不能得到以前的会话域的信息?
不会获得会话域中的信息了,因为会话ID默认在会话结束(浏览器关闭)就销毁了
2.如果浏览器关闭,服务器上的会话信息还存在吗?
存在,服务器会话域的数据默认的过期时间是1800秒
3.如何让浏览器关闭还可以再访问服务器上没有过期的信息?
设置会话ID过期时间,自己保持会话ID
1.创建Cookie,用来封装会话ID,名字必须是JSESSION
2.设置过期时间:
cookie.setMaxAge(600)
,设置过期时间为10分钟3.交给浏览器
设置会话过期时间
1.设置最大非活动间隔时间:
setMaxInactiveInterval(int time)
2.通过配置文件web.xml配置:单位是分钟
<session-config>
<session-timeout>10<session-timeout>
<session-config>
3.立即销毁会话:invalidate(),一半用在注销或者退出
Session和Cookie的小结
技术类型 | 数据存储位置 | 键值对数据类型 | |
---|---|---|---|
Cookie | 浏览器端会话技术 | 客户端的本地文件 | String,String |
Session | 服务器端会话技术 | 服务器端的内存 | String,Object |
单个Cookie保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个Cookie
Cookie不是很安全,别人可以分析存放在本地的Cookie并进行本地欺骗,考虑到安全应当使用Session
如何选择Cookie和Session?
如果数据比较大或者包含隐私数据则选择Session,否则可以选用Cookie
会话的钝化与**
浏览器关闭的时候,服务器端的会话数据会销毁吗?
不会
服务器关闭的时候,服务器端的会话数据会销毁吗?
不会
概述
在正常情况下,服务器关闭或重启的时候,服务器会将所有会话域中的数据以文件的形式保存在服务器的硬盘上,下次服务器重新启动的时候,再读取硬盘上的这些文件把他们还原。
会话的钝化
服务器将会话域的数据保存在文件中的过程
会话的**
服务器将文件的数据读取到会话域中的过程
钝化和**过程由Tomcat完成,程序员不用理会,只需要保证对象必须实现序列化接口
URL重写-禁用Cookie的处理
实现浏览器禁用Cookie后仍然能够访问服务器上Session的数据
URL重写
对URL进行改写:在URL后面拼接会话ID
相关方法
URL重写相关方法 | 说明 |
---|---|
response.encodeRedirectURL(path) |
将重定向的地址进行重写,添加一个会话ID在后面。 |
response.encodeURL(path) |
将要跳转到的地址(链接或表单地址)进行URL重写 添加一个会话ID在后面。 |
重定向URL重写代码:
// 设置内容类型和编码 response.setContentType("text/html;charset=utf-8"); // 获得字符打印流 PrintWriter out = response.getWriter(); // 获取会话域对象(第一次调用getSession方法才会分配内存区域,并分配一个会话ID) HttpSession session = request.getSession(); // 创建产品对象 Product product = new Product("IPone12"); // 往会话域中存储数据 session.setAttribute("product", product); // 重定向到demo02 String url = "demo02"; System.out.println("重写前:"+url); // 对要重定向的地址进行重写 url = response.encodeRedirectURL(url); System.out.println("重写后:"+url); response.sendRedirect(url);
对超链接URL重写:
String url = "demo02"; // 对超链接的地址进行重写 url = response.encodeURL(url); out.println("<a href='"+url+"'>查询产品信息</a>");
Servlet三个作用域总结
作用域的创建和销毁
作用域 | 接口名 | 作用范围 | 生命周期 |
---|---|---|---|
请求域 | HttpServletRequest |
同一个请求 | 请求开始到请求结束 |
会话域 | HttpSession |
同一个会话 | 会话开始到会话结束 |
上下文域 | ServletContext |
同一个应用 | 服务器启动到关闭 |
作用域共同的方法
功能 | 方法名 |
---|---|
存放数据 | setAttrbute |
获取数据 | getAttrbute |
删除数据 | removeAttrbute |
如何选择作用域
如果小范围的作用域能够满足需要就使用小范围的作用域
请求域 < 会话域 < 上下文域