会话跟踪技术(Cookie & Session)

一、前言

会话跟踪技术

  • 会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中,可以包含多次请求与响应。
  • 会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据
  • HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享。

CookieSession指的是什么?

  • Cookie与Session是域对象,所谓域就相当于给存储的内容设置一个边界,将存储的内容存储到这片区域内。例如我们要实现购物车添加或删除商品,就需要使用Cookie与Session技术。

二、Cookie

1. Cookie基本原理及使用

  • Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。
  • Cookie的实现基于HTTP协议
  • 请求头:cookie
  • 响应头:set-cookie
  • Cookie的工作原理

① 客户端第一次发送请求到服务器端。
② 服务器端创建Cookie,该Cookie中包含相关信息,然后将该Cookie发送到客户端。
③ 客户端再次访问服务器端时会携带服务器端创建的Cookie。
④ 服务器端通过Cookie中携带的数据区分不同的用户。

  • Cookie使用:

发送Cookie

①创建Cookie对象,设置数据

Cookie cookie = new Cookie(key, value);

②发送Cookie到客户端:使用Response对象

response.addCookie(cookie);

测试代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// 1. 创建 Cookie 对象
	Cookie cookie = new Cookie("key", "value");
	// 2. 发送 Cookie
	response.addCookie(cookie);
}

获取Cookie

①获取客户端携带的所有Cookie:使用Request对象

Cookie[] cookies = request.getCookies();

②遍历数组,获取每一个Cookie对象
③使用Cookie对象方法获取数据

cookie.getName();		// 获取键的内容
cookie.getValue();		// 获取值的内容

测试代码

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// 获取 cookie
	Cookie[] cookies = request.getCookies();
	// 遍历数组
	for(Cookie cookie:cookies){
		// 获取数据
		String name = cookie.getName();
		if(name.equals("所需要的cookie键值")){
			String value = cookie.getValue();
			// 相应处理
		}
	}
}

2. 关于Cookie

Cookie存活时间

默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,Cookie被销毁。

设置方法: setMaxAge(int seconds) 设置Cookie存活时间。

  1. 正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
  2. 负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie销毁
  3. 删除对应Cookie

Cookie存储中文数据

Cookie不能直接存储中文。 若需要存储,则需要进行转码:URL编码,一般使用UTF-8编码即可。不推荐使用GBK等中文编码,因为浏览器不一定支持,而且JavaScript也不支持GBK编码。

示例如下:

创建Cookie:

String value = "划水艺术家";
// URL 编码
value = URLEncoder.encode(value, "UTF-8");
Cookie cookie = new Cookie("username", value);

获取Cookie:

String name = cookie.getName();
if(name.equals("username")){
	String value = URLDecoder.decode(cookie.getValue(), "UTF-8");
}

Cookie获取范围

  • 同一服务器中多项目Cookie共享问题
  1. 默认情况下不能共享
  2. setPath(String path):设置Cookie的获取范围,默认为当前虚拟目录路径。
    如果想要同一服务器中多项目共享Cookie,可以将path设置为 “/”,即setPath("/")

  • 不同服务器Cookie共享问题
  1. setDomain(String path):如果设置一级域名相同,那么多个服务器之间Cookie可以共享,path变量必须以.开头
  2. setDomain(".abc.com"):那么aaa.abc.com和bbb.abc.com中Cookie可以共享

Cookie常用API

Cookie 对象操作方法

// 设置与 Cookie 对象的值。
void setValue()
// 获取与 Cookie 对象的值。
String getValue()
// 设置 Cookie 存活时间(以秒为单位)
void setMaxAge()
// 获取 Cookie 存活时间(以秒为单位)
int getMaxAge()
// 设置 Cookie 适用的路径
void setPath()
// 获取 Cookie 适用的路径
String getPath()
// 设置 Cookie 适用的域
void setDomain()
// 获取 Cookie 适用的域
String getDomain()

Response 对象操作方法

// 在响应头中增加一个相应的 Set-Cookie头字段
void addCookie();

Request 对象操作方法

// 获取客户端携带的 Cookie
Cookie[] GetCookie()

三、Session

1. Session基本原理及使用

  • Session:服务端会话技术,将数据保存到服务端。
  • 本质上:Session技术就是一种基于后端有别于数据库的临时存储技术。
  • JavaEE提供HttpSession接口,来实现一次会话的多次请求间数据共享功能。
  • Session的常用实现有两种方式:

① 基于Cookie

客户端第一次发送请求时,服务器会创建一个Session,同时创建的特殊Cookie(key为JSESSIONID,value为一个唯一Session的id),然后将该Cookie发送至客户端。Session保存在服务器端,为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。

URL重写

URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。
HttpServletResponse类提供了两个URL地址重写的方法

  • encodeURL(String url):用于对表单action和超链接的url地址进行重写
  • encodeRedirectURL(String url):用于对sendRedirect方法后的url地址进行重写

这两个方法会自动判断该浏览器是否支持Cookie,如果支持Cookie,重写后的URL地址就不会带有JSESSIONID了【即使浏览器支持Cookie,第一次输出URL地址时仍然会出现JSESSIONID(因为没有任何Cookie可带)】

URL重写测试代码

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// 获取 session 对象
	HttpSession session = request.getSession();
	// 获取URL
	String url = String.valueOf(request.getRequestURL());
	// URL 重写
	url = response.encodeURL(url);
	// 存储 数据
	session.setAttribute("username", "划水艺术家");
	// 请求转发
	response.sendRedirect(url);
}

可在第一次在URL重写后,将JSESSSIONID返给前端,前端在以后的每次请求都携带上JSESSSIONID。

  • Session的工作原理(基于Cookie)

① 客户端第一次发送请求到服务器端,服务器端创建一个Session,同时会创建一个特殊的Cookie(key为JSESSIONID,value为一个唯一Session的id),然后将该Cookie发送至客户端。

② 客户端发送第N(N>1)次请求到服务端,客户会携带该key为JSESSIONID的Cookie对象。

③ 服务端再次接收到来自客户端的请求时,会先去检查是否存在SessionID,不存在就新建一个SessionID并重复1,2的流程;如果存在就去遍历服务端的session文件,找到与这个SessionID相对应的文件,确定当前用户信息。此后的请求都会交换这个 SessionID,进行有状态的会话。

  • Session使用:

①获取Session对象

HttpSession session = request.getSession();

②Session对象功能

// 存储数据到Session域中
void setAttribute(String key, Object o);
// 根据key,获取值
Object gettAttribute(String key);
// 根据key,删除该键值对
void removeAttribute(String key);

测试代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// 存储数据到 session
	// 1. 获取 session 对象
	HttpSession session = request.getSession();
	// 2. 存储 数据
	session.setAttribute("username", "划水艺术家");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// 从 session 获取数据
	HttpSession session = request.getSession();
	String username = (String) session.getAttribute("username");
}

2. 关于Session

Session钝化、活化

钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘文件
活化:再次启动服务器后,从文件中加载数据到Session


Session销毁

①默认情况,无操作,30分钟自动销毁(自动销毁为防止内存溢出),可在web.xml配置或使用setMaxInactiveInterval(int time)设置。

<session-config>
	<session-timeout>30</session-timeout>
</session-config>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	HttpSession session = request.getSession();
	// 设置超时时间
	session.setMaxInactiveInterval(30);
}

②调用Session对象的invalidate()方法

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	HttpSession session = request.getSession();
	// 销毁
	session.invalidate();
}

Session常用API

以下API均由 Session 对象操作

// 设置 Session 属性
void setAttribute(String key, Object var)
// 获取 Session 属性
Object getAttribute(String key)// 删除 Session 属性
void removeAttribute(String key)
// 销毁 Session
void invalidate()
// 获取 Session 创建时间
long getCreationTime()
// 获取 Session 的id
String getId()
// 获取 Session 最后活跃的时间
long getLastAccessedTime()
// 设置 Session 超时时间
void setMaxInactiveInterval(int var1)
// 获取 Session 超时时间
int getMaxInactiveInterval()
// 判断该 Session 是否为新建
boolean isNew()

四、Cookie与Session总结

  • Cookie与Session都是为完成一次会话内多次请求间数据共享
    两者区别对比:
  • 存储位置:Cookie将数据存储在客户端;Session将数据存储在服务端
  • 存储容量:Cookie最大4KB;Session无大小限制
  • 存储时间:Cookie可长期存储;Session默认30分钟
  • 存储方式:Cookie只能存储ASCII字符,存储unicode字符需要编码;Session能存储任何类型数据,包括但不限于String、Integer、List、Map等。
  • 安全性:Cookie不安全;Session安全
  • 服务器性能:Cookie不占服务器资源;Session占用服务器资源
  • 存活时间:Cookie是按累积时间计算生命周期;Session周期指的是不活动的时间,若设置Session超时时间是10s,在10s内,没有访问Session,Session中属性失效,如果在9s的时候,访问了Session,则会重新计时
  • 跨域名:Cookie可以设置domain属性来实现跨域名;Session只在当前的域名内有效,不可跨域名
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值