Session与Cookie
Session会话
用户打开浏览器,进行一系列操作,然后最终将浏览器关闭,这个整个过程叫做:一次会话。会话在服务器端也有一个对应的java对象,这个java对象叫做:Session。
用户在浏览器上点击了一下,然后到页面停下来,可以粗略认为是一次请求。请求对应的服务器端的java对象是:Request。
一个会话当中包含多次请求。(一次会话对应N次请求。)
在java的servlet规范当中,session对应的类名:HttpSession(javax/jarkata.servlet.http.HttpSession)
session对象最主要的作用是:保存会话状态。
为什么需要session对象来保存会话状态?
- 因为HTTP协议是一种无状态协议(请求的时候,B和S是连接的,但是请求结束之后,连接就断了)。
- 无状态协议,可以降低服务器的压力。请求的瞬间是连接的,请求结束之后,连接断开,这样服务器压力小。
- 只要B和S断开了,服务器是不知道浏览器关闭的。
session对象的销毁方式:
- 超时销毁
- 手动销毁:
session.invalidate();
请求域、会话域和应用域
请求域(请求级别的)
- request(对应的类名:HttpServletRequest)
请求开始时创建,请求结束时销毁。
会话域(用户级别的)
- session(对应的类名:HttpSession)
会话开始时创建,会话结束时销毁。
应用域(项目级别的,所有用户共享的。)
- application(对应的类名:ServletContext)
服务器启动时创建,服务器关闭时销毁
这三个域对象的大小关系
- request < session < application
他们三个域对象都有以下三个公共的方法:
- setAttribute(向域当中绑定数据)
- getAttribute(从域当中获取数据)
- removeAttribute(删除域当中的数据)
使用原则:尽量使用小的域。
获取session
// 获取session对象,如果没有获取到则新建
HttpSession session = request.getSession();
// 获取session对象,如果没有获取到则不会新建,返回null
HttpSession session = request.getSession(false);
设置session的超时时间
web.xml
<!--设置session的超时时长为30分钟-->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
session的实现原理
- JSESSIONID=xxxxxx 这个是以Cookie的形式保存在浏览器的内存中的。浏览器只要关闭。这个cookie就没有了。
- session列表是一个Map,map的key是sessionid,map的value是session对象。
- 用户第一次请求,服务器生成session对象,同时生成id,将id发送给浏览器。
- 用户第二次请求,自动将浏览器内存中的id发送给服务器,服务器根据id查找session对象。
- 关闭浏览器,内存消失,cookie消失,sessionid消失,会话等同于结束。
cookie禁用(服务器正常发送cookie给浏览器,但是浏览器拒收了)了,session还能找到吗?
- 找不到了。每一次请求都会获取到新的session对象。
- cookie禁用了,session机制还能实现吗?
- 可以。需要使用URL重写机制。
- http://ip:端口号/路径;jsessionid=xxxxxx
- URL重写机制会提高开发者的成本。开发人员在编写任何请求路径的时候,后面都要添加一个sessionid,给开发带来了很大的难度,很大的成本。所以大部分的网站都是这样设计的:你要是禁用cookie,你就别用了。
Cookie缓存
在java的servlet规范当中,cookie对应的类名:Cookie(javax/jakarta.servlet.http.Cookie)
cookie没有无参构造,任何一个cookie都是要传入name字符串和value字符串
cookie最终是保存在浏览器客户端上的。
- 可以保存在运行内存中。(浏览器只要关闭cookie就消失了)
- 也可以保存在硬盘文件中。(永久保存)
cookie的作用:
- cookie和session机制其实都是为了保存会话的状态。
- cookie是将会话的状态保存在浏览器客户端上。(cookie数据存储在浏览器客户端上的)
- session是将会话的状态保存在服务器端上。(session对象是存储在服务器上)
- 为什么要有cookie和session机制呢?因为HTTP协议是无状态 无连接协议。
将cookie响应到浏览器
@WebServlet("/cookie/generate")
public class GenerateCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建Cookie对象
Cookie cookie = new Cookie("produtid","12345656214332");
// 没有设置有效时间:默认保存在浏览器的运行内存中,浏览器关闭则cookie消失。
// 只要设置cookie的有效时间 > 0,这个cookie一定会存储到硬盘文件当中。
// 设置cookie的有效时间 = 0,表示该cookie被删除,浏览器同名cookie会被删除。
// 设置cookie的有效时间 < 0,表示该cookie不会被存储。保存在运行内存中,和不设置一样。
// 设置cookie的失效时间(以秒为单位)
//cookie.setMaxAge(60*60); // 1个小时后失效
//cookie.setMaxAge(0);
cookie.setMaxAge(-1);
// 设置cookie的path,表示只要是这个项目的请求路径,都会提交这个cookie给服务器。
cookie.setPath(request.getContextPath());
// 将cookie响应到浏览器
response.addCookie(cookie);
}
}
关于cookie的path:
假设是 http://ip:端口号/项目名/cookie/generate 发送的cookie,只要浏览器的请求路径是http://ip:端口号/项目名/cookie 这个路径以及这个路径下的子路径,cookie都会被发送到服务器。
浏览器发送cookie给服务器
@WebServlet("/sendCookie")
public class ReceiveCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Java程序通过request对象接收浏览器发送过来的cookie。
// 如果浏览器没有提交cookie,这个方法的返回值是null,并不是一个长度为0的数组。
Cookie[] cookies = request.getCookies();
// cookies不为null,表示一定有cookie
if (cookies != null) {
// 遍历数组
for (Cookie cookie : cookies) {
// 获取cookie的name和value
String name = cookie.getName();
String value = cookie.getValue();
System.out.println(name + "=" + value);
}
}
}
}
cookie和session
cookie机制和session机制其实都不属于java中的机制,实际上cookie机制和session机制都是HTTP协议的一部分。只要是你是做web开发,不管是什么编程语言,cookie和session机制都是需要的。
cookie和session的区别:
cookie数据
存放在客户的浏览器
上,session数据
放在服务器
上。- cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用服务器的性能。
- 考虑到
安全
使用session
,考虑到减轻服务器性能
方面使用cookie
- 单个cookie在客户端的限制是
3K
(最大只能存放3K的数据)。
cookie和session的共同点:
- cookie&session能够始终存在于从一个浏览器发起的一系列的
请求及响应
中且在此期间都是共享的同一个对象、这样的特性使得两者都可以用来保存客户的状态信息。