会话跟踪技术(一):Session和Cookie技术
当你访问网站时,在线服务商会将一小份信息放置在您的计算机上。这一小份信息被称为Cookie(可扩展数据对象),它会记录下您在网站上的某些行为或选择(例如输入的文字或所做的选择)。当您再次访问同一个网站时,在线服务商会根据您上一次Cookie记录的内容来展示相应的网页内容。例如,在使用电子邮件服务的网站时,Cookie可以帮助系统记住您的偏好设置和登录信息等个人资料。
具体来说,Cookie机制是基于客户端持久化技术的设计方案,它通过记录用户的浏览行为来提供个性化服务,而session机制则依赖于服务器端的数据持久化技术,通过维持会话上下文来实现类似的功能。
一.什么是会话技术:
对话 可以被定义为客户端与服务器之间的一次互动,在一次对话中可能包含多个请求和相应的响应机制。例如当你拨打10086服务电话时,“你”扮演着客户端角色,“10086服务人员”则扮演着服务器角色。自双方接通电话那一刻起,“对话”便开始了;当某一方挂断电话表示对话结束时,“对话”也随之终止。“对话”的进行涉及多个步骤:客户向指定服务器发送第一个请求时,“对话”便启动;直到客户关闭浏览器窗口为止,“对话”的结束标志着其自然终止。“对话”的多个步骤中需要共享必要的数据信息——这就是所谓的“对话跟踪技术”。以具体步骤为例:
(1) 请求访问银行主页;
(2) 发出登录请求(需提供用户名和密码);
(3) 发出转账请求(需提供相关转账数据);
(4) 发出还贷请求(需提供相关还款数据)。
在整个上述过程中当前用户的信息必须被共享——因为登录的是张三账户——因此,在转账和还贷操作中必定是针对张三的交易行为!这就凸显出必须在一个完整的对话过程中具备共享数据的能力。
二.Cookie技术
HTTP属于无状态通信协议,在这种架构下每次请求均独立运行;不具备记录上一次操作的能力。然而,在HTTP标准框架内仍可通过采用Cookie机制实现会话追踪功能;在Java Web开发环境中,则主要通过Session组件实现会话管理;其中Session机制默认依赖于Cookie技术作为数据存储基础。
1.Cookie概述
1.1什么叫Cookie
由于这是一个技术文档中的关键概念介绍段落,在改写时应保持专业性和准确性的同时适当降低重复率
1.2Cookie规范:
- Cookie的最大尺寸限定为4KB。
- 单个服务器最多能在客户端浏览器中存储20个独立的Cookie。
- 普通浏览器通常能够存储多达300个独立的Cookie。
当然这些数据主要基于HTTP标准的规定但在 browser 竞争激烈的今天许多 browsers为了增强自身竞争力可能会对这一标准进行一定程度上的"扩展"例如单个 Cookie 的最大尺寸可达8KB 并且可支持高达500个独立 Cookie 的配置!不过这样的设计也不会导致用户的本地硬盘空间被过度占用。
需要注意的是不同 browsers之间不会共享 Cookie信息也就是说当您通过 IE 浏览器访问服务器时 服务器会将生成的所有 Cookies 发送给 IE 让其自行管理;而当您切换到 Firefox 浏览器时由于其与 IE 不属于同一个网络环境因此无法获取其他浏览器发送来的 Cookies。
1.3Cookie与HTTP头:
Cookie通过HTTP请求及其响应头在客户端与服务器之间传递。
(1)其中 Cookie字段作为请求头部信息被客户端发送至服务器。
格式上可表示为 Cookie: a=A; b=B; c=C 即多个 Cookie 以分号分隔。
(2)而 Set-Cookie字段则作为响应头信息传递至客户端。
单个 Cookie 对象对应唯一一个 Set-Cookie 字段分别设置不同属性值。
1.4Cookie的覆盖
若服务器端连续发送相同的Cookie,则会覆盖原有的Cookie。例如,在第一个请求中,服务器向客户端发送了Cookie:a=A;在第二个请求中,则发送了a=AA。因此,在两个请求中仅存的唯一Cookie即为a=AA。
1.5Cookie的第一个例子:
当客户端打开AServlet时,在响应阶段生成Cookie并存储到本地存储;随后浏览器会将此Cookie传递给相关网页应用进行显示处理。接着当客户端再次打开BServlet时,在请求阶段携带由上一次操作产生的Cookie信息,并将这些信息传递给服务器端处理以完成后续操作。

AServlet.java如下:
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String id = UUID.randomUUID().toString();//生成一个随机字符串
Cookie cookie = new Cookie("id", id);//创建Cookie对象,指定名字和值
response.addCookie(cookie);//在响应中添加Cookie对象
response.getWriter().print("已经给你发送了ID");
}
}
BServlet.java如下:
public class BServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
Cookie[] cs = request.getCookies();//获取请求中的Cookie
if(cs != null) {//如果请求中存在Cookie
for(Cookie c : cs) {//遍历所有Cookie
if(c.getName().equals("id")) {//获取Cookie名字,如果Cookie名字是id
response.getWriter().print("您的ID是:" + c.getValue());//打印Cookie值
}
}
}
}
2.Cookie的生命
以下是经过同义改写的文本
3.Cookie的path
3.1什么是Cookie的路径
目前有一个WEB应用程序A向所有客户端发送了一个特定数量的cookie,这意味着无论客户如何访问该Web程序中的任何Servlet(即任何单个或组合),都会将该cookie集合包括在相应的HTTP请求中!然而,实际上可能存在这样的情形:只有一个或者少数几个Servlet会继承并处理这些cookie,而其他的ServletContext则不会直接获取这些cookie.这也表明,在某些情况下(比如当一个前端框架初始化多个前端实例时),浏览器可能会多发一些cookie到网络中!此外,通过设置cookie的path属性来指导浏览器,在哪些路径下会包含哪些cookies.
3.2Cookie路径与请求路径的关系
我们深入探讨了Cookie路径的功能:客户端浏览器保存了三个Cookie的路径如下:
a: /cookietest;
b: /cookietest_servlet;
c: /cookietest_jsp;
对于浏览器而言,其请求的URL信息为:
A: http://localhost:8080/cookietest/AServlet;
B: http://localhost:8080/cookietest/servlet/BServlet;
C: http://localhost:8080/cookietest/jsp/CServlet;
- 当发起请求A时,在请求体中会包含字段a。
- 在发起请求B的过程中,在请求体中会包含字段a和b。
- 当发起请求C的时候,在响应头信息里会有字段a以及c字段。
换句话说,在请求头信息中如果包含了Cookies的路径信息,则会将该Cookies发送到客户端;反之则不会发送到客户端
- 由于A请求的URL包含了" / cooki test "(注:此处可能应更正为" / cooki test "),该请求会被构造出包含路径为" / cooki test "(注:此处可能应更正为" / cookiejtest ")的Cookie;
- B请求的URL包含了" / cooki test "(注:此处可能应更正为" / cookiejtest ")及其子目录" / cooki test / servlet "(注:此处可能应更正为" cookiejtest / servlet "),因此该请求会被构造出包含路径分别为" / cookiejtest "及" cookiejtest / servlet "两个Cookie;
- C请求的URL包含了" / cookie jst est "(注:此处可能应更正为" cookie jst est "/),其子目录包括" cookie jst est / jsp "(注:此处可能应更正为"/ jsp/"),因此该请求会被构造出包含路径分别为" cookie jst est "/及' cookie jst est '/jsp'两个Cookie;
3.3设置Cookie的路径
要为Cookie设置路径,请调用setPath()方法。cookie.setPath(“/cookietest/servlet”);如果未为Cookie指定路径,则其默认取自当前访问资源的路径;例如:在<http://localhost:8080/cookietest/AServlet>中添加的Cookie默认路径为/cookietest;在<http://localhost:8080/cookietest/servlet/BServlet>中添加的Cookie默认路径则为/cookietest/servlet;在<http://localhost:8080/cookietest/jsp/BServlet>中添加的Cookie默认路径则为/cookietest/jsp。
4.Cookie中保存中文
向客户端响应中添加Cookie
向客户端响应中添加Cookie
String name = URLEncoder.encode("姓名", "UTF-8");
String value = URLEncoder.encode("张三", "UTF-8");
Cookie c = new Cookie(name, value);
c.setMaxAge(3600);
response.addCookie(c);
从客户端请求中解析Cookie:
`Cookie[] cs = request.getCookies();
if (cs != null) {
for (Cookie c : cs) {
String name = URLDecoder.decode(c.getName(), "utf-8");
String value = URLDecoder.decode(c.getValue(), "utf-8");
System.out.println(name + "=" + value);
}
}
三.Session技术:
1.session的实现原理
当我初次踏入银行时
当再次进入银行时
当第一次使用session时
当客户端再次访问服务器时

2.session与浏览器
session 存储于服务器端,并通过 Cookie 将 sessionId 发送给客户端设备。然而,请注意该 Cookie 仅存在于浏览器内存中,并不具备自动清除功能。因此,在用户关闭浏览器后将无法访问该 Cookie 对象。
当用户再次启动浏览器并访问服务器时,则将无法向服务器发送 sessionID。此时将无法向服务器发送 sessionID。
因此, 服务器会认为当前用户未登录。
原有的 session 对象又会如何?当某个 session 长时间无人使用时, 该 session 将会被 Tomcat 自动删除。
此设置可以在 ${CATALANA}/conf/web.xml 中找到具体配置参数, 其默认值设置为 30 分钟.
需要注意的是, 如果某人长时间未操作页面内容, 超过指定的时间限制后返回的响应将包含一个重新生成的 sessionId Cookie。
3.session其他常用API
- String getId():获取会话ID;
- int getMaxInactiveInterval():获取会话的最大静默时间段(秒数),其默认设置为30分钟。若会话处于静默状态超过30分钟,则Tomcat将在会话池中删除该会话;
- void setMaxInactiveInterval(int interval):配置会话的最大静默时间段(秒数)。若设置值仅为1秒,则表示只要该会话未被使用超过1秒钟就会被删除;
- long getCreationTime():提供会话创建的时间戳(毫秒单位);
- long getLastAccessedTime():提供最新的访问时间戳(毫秒单位);
- void invalidate():使该会话失效!此操作将导致失效后的客户机在下次请求时将自动重创建新的会话,并在响应中包含新的Session ID;
- boolean isNew():判断当前是否是新 session。若客户机首次发起请求而尚未收到服务器回复,则表示系统尚未生成相应的Session ID
4.URL重写
我们知道session依赖Cookie,那么session为什么依赖Cookie呢?因为服务器需要在每次请求中获取sessionId,然后找到客户端的session对象。那么如果客户端浏览器关闭了Cookie呢?那么session是不是就会不存在了呢?
其实还有一种方法让服务器收到的每个请求中都带有sessioinId,那就是URL重写!在每个页面中的每个链接和表单中都添加名为jSessionId的参数,值为当前sessionid。当用户点击链接或提交表单时也服务器可以通过获取jSessionId这个参数来得到客户端的sessionId,找到sessoin对象。
在index.jsp中配置:
<body>
<h1>URL重写</h1>
<a href='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' >主页</a>
<form action='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' method="post">
<input type="submit" value="提交"/>
</form>
</body>
除了我们之前手动添加的方式外
<a href='<%=response.encodeURL("/day06_5/index.jsp") %>' >主页</a>
<form action='<%=response.encodeURL("/day06_5/index.jsp") %>' method="post">
<input type="submit" value="提交"/>
</form>
使用response.encodeURL()特别智能化
四.cookie 和session 的区别:
1、cookie数据被存储在用户的浏览器端设备中,而session数据则被存储在服务器端。
2、由于存在被他人解析的风险和其他潜在的安全漏洞问题,others can analyze the cookie data stored locally and perform a cookie hijacking attack.
3、 sessions are typically maintained on the server side for a defined period, and as user numbers increase, this can lead to higher server load.
4、each individual cookie can store up to 4 kilobytes of data.
5、为了保护用户隐私和安全起见,在推荐的情况下应优先考虑将关键登录信息等重要数据存储为session;对于非关键性的辅助数据,则可选择以cookie的形式进行存储。
