Session会话追踪的实现机制

一、概述

        因为HTTP协议是一个无状态协议,即Web应用程序无法区分收到的两个HTTP请求是否是同一个浏览器发出的。为了跟踪用户状态,服务器可以向浏览器分配一个唯一ID,并以Cookie的形式发送到浏览器,浏览器在后续访问时总是附带此Cookie,这样,服务器就可以识别用户身份。

二、Session

        我们把这种基于唯一ID识别用户身份的机制称为Session。每个用户第一次访问服务器后,会自动获得一个Session ID。如果用户在一段时间内没有访问服务器,那么Session会自动失效,下次即使带着上次分配的Session ID访问,服务器也认为这是一个新用户,会分配新的Session ID。一次Session会话中往往包含着若干次request请求。

  JavaEEServlet机制内建了对Session的支持。当我们需要获取Session时,可以通过request请求对象的getSession()方法。例如:

package com.apesource.web.servlet;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/test_session.do")
public class TestSeesionServlet extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("Get请求:TestSeesionServlet被请求到了");
		
		// 第一次在访问Session时,服务器会创建Session
		// 并根据Session_ID,创建一个1个名称为"JSESSIONID"的Cookie
		HttpSession session = req.getSession();
		System.out.println(session.getId());
		
	}
}

获取HttpSession后,常见的操作方法有:

  • void setAttribute(String name, Object value):将指定Key-Value键值对,存入当前Session会话中。
  • Object getAttribute(String name):按照指定的Key从当前Session会话中获取Value,返回值为Object类型的对象,如果不存在,则返回null
  • void removeAttribute(String name):按照指定的Key从当前Session会话中删除Key-Value键值对。
  • long getCreationTime():获取当前Session会话的创建时间。
  • long getLastAccessedTime():获取当前Session会话最后一次请求的访问时间。
  • String getId():获取当前Session会话的SESSION ID

        服务器识别Session的关键就是依靠一个名为JSESSIONIDCookie。在Servlet中第一次调用req.getSession()时,Servlet容器自动创建一个Session ID,然后通过一个名为JSESSIONIDCookie发送给浏览器。

        使用Session时,由于服务器把所有用户的Session都存储在内存中,如果遇到内存不足的情况,就需要把部分不活动的Session序列化到磁盘上,这会大大降低服务器的运行效率,因此,放入Session的数据不能太大,否则会影响服务器的运行。 

三、Cookie

        实际上,Servlet提供的HttpSession本质上就是通过一个名为JSESSIONIDCookie来跟踪用户会话的。除了这个名称外,其他名称的Cookie我们可以任意使用。

        创建一个新Cookie时,除了指定名称和值以外,通常需要设置setPath("/"),浏览器根据此前缀决定是否发送Cookie。如果一个Cookie调用了setPath("/user/"),那么浏览器只有在请求以/user/开头的路径时才会附加此Cookie。通过setMaxAge()设置Cookie的有效期,单位为秒,最后通过resp.addCookie()把它添加到响应。

        通过创建Cookie,我们可以实现在客户端浏览器中存储数据的目的,例如保存用户名和密码。在Chrome浏览器中,单个 Cookie的长度不能超过 4069 个字符(包括 name,但不包括 = 号)。

我们可以在浏览器看到服务器发送的Cookie

如果我们要读取Cookie

package com.apesource.web.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/test_get_cookie.do")
public class TestGetCookieServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("测试获取Cookie!");
		
		// 获取该客户端浏览器本次请求头(Request Header)中所有的Cookie
		Cookie[] cookie = req.getCookies(); 
		
		if(cookie != null) {
			for (Cookie ck : cookie) {
				System.out.println(ck.getName());
				System.out.println(ck.getValue());
				System.out.println();
			}
			
		}
	}

}

所以,读取Cookie主要依靠遍历HttpServletRequest附带的所有Cookie

 小结:

  • Servlet容器提供了Session机制以跟踪用户;
  • 默认的Session机制是以Cookie形式实现的,Cookie名称为JSESSIONID
  • 通过读写Cookie可以在客户端存储数据;

 

 

 

 

 

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...