微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Session会话追踪的实现机制

一、概述

在Web应用程序中,我们经常要跟踪用户身份。例如:当一个用户登录成功后,如果他继续访问其他页面,Web程序如何才能识别出该用户身份?当一个用户在操作自己的购物车时,Web程序如何才能识别出该用户身份?

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

二、Session和Cookie

1.Session

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

  • 当我们第一次在访问Session时,服务器会创建Session
  • 并根据Session_ID,创建一个名称为“JSESSIONID”的Cookie,将Session_ID保存至Cookie
  • 将该Cookie响应回至浏览器客户端保存
  • 接下来的每次发起请求时,客户端浏览器都会在请求头中,添加JSESSIONID
  • 用于服务器确认“身份”
  • (需要获取Session时,可以通过request请求对象的getSession()方法。String getId():获取当前         Session会话的SESSION ID。)
package com.my.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 TestSessionServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws servletexception, IOException {
		System.out.println("GET请求:TestSessionServlet被请求到了!");
		HttpSession session = req.getSession();
		System.out.println("SESSIONID:" + session.getId());
		
	}
}

8320f5d5fe99410fa810668c0e7b536f.png

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

9049e1d8a0a545858d124a6231c1a9f2.png

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

2、Cookie

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

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

①通过创建Cookie,我们可以实现在客户端浏览器中存储数据的目的,例如保存用户名和密码。

package com.my.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_cookie.do")
public class TestCookieServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
		System.out.println("Cookiiiiiiiiiiiiiiiie");
		
		//创建Cookie对象
		Cookie cookie1 = new Cookie("phone_number", "13309270719");
		cookie1.setMaxAge(60*60*24*7);//7天
		
		Cookie cookie2 = new Cookie("name", "YY");
		cookie1.setMaxAge(60*60*24*7);//7天
		
		Cookie cookie3 = new Cookie("QQ", "2452845234");
		cookie1.setMaxAge(60*60*24*7);//7天
		
		//响应
		response.addCookie(cookie1);//将Cookie添加至响应头
		response.addCookie(cookie2);
		response.addCookie(cookie3);
		
		
	}
}

aafa4b3300bf4f81b604e787daad7b9d.png

 这样就成功保存了想要保存的信息至客户端浏览器啦。

②如果想要获取该客户端浏览器本次请求头(request header)中的所有Cookie

package com.my.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 request, HttpServletResponse response) throws servletexception, IOException {
		System.out.println("测试获取Cookie!");
		
		//获取该客户端浏览器本次请求头(request header)中的所有Cookie
		Cookie[] cookies = request.getCookies();
		
		for (Cookie cookie : cookies) {
			System.out.println(cookie.getName());
			System.out.println(cookie.getValue());
			System.out.println();
		}
	}
}

1f9545d9d8444c5fb8489b8ab75b60dd.png

获取应用范围的总访问量

package com.my.web.servlet;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.servletexception;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/test_app.do")
public class TestApplicationServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
		//应用范围
		ServletContext application = request.getServletContext();
		System.out.println("Context Path :" + application.getcontextpath());
		System.out.println("Real Path:" + application.getRealPath("/"));
		
		if(application.getAttribute("app_counter") == null) {
			application.setAttribute("app_counter", 1);
			System.out.println("总访问量:1");
		}else {
			int appCounter = Integer.parseInt(application.getAttribute("app_counter").toString());
			application.setAttribute("app_counter",appCounter+1);
			System.out.printf("总访问量:%d\n" , appCounter+1);
		}
	}
}

6593e05e47c1441b891aa0475b49a0e2.png

 

 

 

原文地址:https://www.jb51.cc/wenti/3279762.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐