跟踪用户状态,http协议无状态 Cookie HttpSession,Session和Cookie的关系

1.概念分析

跟踪用户状态指的是web应用能够分辨请求属于哪个用户,进而记录用户的状态,从而为用户提供连续的针对性的服务。比如有多个客户在同一个购物网站上购物,每一个用户都会有一个虚拟的购物车。当某个客户发送请求将商品添加到购物车时,Web服务器必须能识别请求属于哪个用户,从而将商品添加该用户的购物车中

大多数的Web应用都需要跟踪用户状态,才能提供对应的服务。常见需要跟踪用户状态的应用:

  • 电子商务

  • 管理系统

也有一些简单的Web应用不需要跟踪用户状态。一些不需要跟踪用户状态的应用:

  • 门户新闻网站

  • 软件下载网站

2.http协议无状态

http协议是无状态的。每发起一次请求,就就创建一个新的连接,当结果响应结束后,连接就会被关闭。1个用户的多次请求和多个用户各发1次请求对于Web服务器而言是没有区别的。Web服务器无法根据连接分辨请求属于哪一个用户,http协议本身没有分辨用户,跟踪用户状态的功能。

解决方案:

  • Cookie

  • HttpSession

3 Cookie

Cookie 并不是它的原意“甜饼”的意思, 而是一个保存在客户机中的简单的文本文件, 这个文件与特定的 Web 文档关联在一起, 保存了该客户机访问这个Web 文档时的信息, 当客户机再次访问这个 Web 文档时这些信息可供该文档使用。由于“Cookie”具有可以保存在客户机上的神奇特性, 因此它可以帮助我们实现记录用户个人信息的功能 。

举例来说, 一个 Web 站点可能会为每一个访问者产生一个唯一的ID, 然后以 Cookie 文件的形式保存在每个用户的机器上。如果使用浏览器访问 Web, 会看到所有保存在硬盘上的 Cookie。在这个文件夹里每一个文件都是一个由“名/值”对组成的文本文件,另外还有一个文件保存有所有对应的 Web 站点的信息。在这里的每个 Cookie 文件都是一个简单而又普通的文本文件。透过文件名, 就可以看到是哪个 Web 站点在机器上放置了Cookie(当然站点信息在文件里也有保存) 。

所谓“cookie”数据是指某些网站为了辨别用户身份,储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。

通俗来讲就是指缓存数据,包括用户名、密码、注册账户、手机号等公民个人信息

3.1 设计思想

超市会员卡

特点:

  • 会员卡保存会员信息由超市生成并提供

  • 会员卡由顾客保存

  • 会员卡一般都会有有效期

  • 超市根据会员卡分辨识别用户

服务端生成包含用户信息的Cookie(键值对字符串),返回客户端。客户端再发起请求时,会自动携带Cookie到服务端,服务端可以获取Cookie,读取到用户信息从而识别用户。

特点:

  • Cookie由服务端生成

  • Cookie有client(浏览器)保存

  • Cookie都会有有效期

  • 服务端根据cookie分辨识别用户

3.2 技术细节

Cookie的使用,我们主要关注2点:服务端如何创建Cookie,以及如何从请求中获取Cookie?

Cookie有效期的设置:

/*
	Cookie有效期,默认等同于浏览器。(浏览器关闭,Cookie销毁)
	可以通过cookie.setMaxAge(存活时长)设置其有效期
*/
   ck.setMaxAge(60*60*24*7);//单位秒

手动添加Cookie

 //手动设置Cookie
        Cookie cookie = new Cookie("classId","202");
        Cookie cookie2 = new Cookie("school",URLEncoder.encode("郑大", "UTF-8"));
        cookie2.setMaxAge(60*60);
        response.addCookie(cookie);
        response.addCookie(cookie2);//获取Cookie       Cookie[] cookies = request.getCookies();
        
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1> 账户:  "+ name +" <br/> 密码:"+ password +"   </h1>");
        for(Cookie cookie : cookies){
            String value = URLDecoder.decode(cookie.getValue(), "UTF-8");
            out.println("<h2> Cookie:  "+ cookie.getName() +" <br/> 值:"+ value +"   </h2>");
        }
        out.println("</body></html>");

Cookie的不足:

  • 只能保存字符串数据

  • 不能直接保存中文字符(tomcat8.5之后可以直接保存)

  • Cookie保存数据量有限,最多4K

  • Cookie不安全

Cookie的最佳实践:使用Cookie保存少量的不重要的数据,比如:浏览记录,用户名

4.HttpSession

HttpSession会话,表示一个浏览器和服务端的多次交互过程。一个浏览器短时间内连续访问服务端始终对应着同一个HttpSession对象.

4.1设计思想

HttpSession对象就好像生活中宾馆的一个房间。一个住客在一个宾馆中居住的日子里始终居住在同一个房间。

特点:

  • 房间由宾馆分配

  • 房间由宾馆管理

  • 每一个房间都会有使用时限

  • 宾馆根据房间和住客的对应关系分辨识别住客

HttpSession对象是由服务端创建的对象,占据服务器的一小块内存空间。一个浏览器(好比住客)多次访问服务端(好比宾馆)始终对应着同1个Session对象。服务端可以根据Session对象分别不同用户。

特点:

  • session由服务端创建

  • session保存在服务端,会占用服务器内存空间

  • session都会有默认的存活时长:距上一次访问30分钟

  • 服务端根据session分辨识别用户,session和浏览器是一一对应的关系。

4.2 技术细节

HttpSession的创建和获取

无论何时获取Session,代码都是:req.getSession(); 如果是第1次获取服务器会新建一个Session,如果之前获取过则直接返回Session。

设置session

/**
 * 使用session共享数据
 */
@WebServlet(name = "s1", value = "/s1")
public class SessionDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //使用session共享数据
        //1.获取session
        HttpSession session = req.getSession();
        //2.存储数据
        session.setAttribute("name", "苍老师");
    }

}

获取session

@WebServlet(name = "s2", value = "/s2")
public class SessionDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
	//使用session获取数据
	//1.获取session
	HttpSession session = req.getSession();
	//2.获取数据
	Object msg = session.getAttribute("name");
	System.out.println(msg);
	

}

4.3 HttpSession作用域对象的使用

HttpSession本身还可以保存、获取数据,也就是可以当做作用域对象使用。因为同1个浏览器的多次请求获取到的是同1个Session,也就可以借助Session作用域在一个浏览器的多次请求间传递数据.

request和session作用范围:

  • request作用域的范围:在一次请求中

  • session的作用域范围:在一个浏览器的多次请求间

4.4 session存活时长的设置

session默认存活时长:距上一次访问30分钟

1. 修改tomcat/conf/web.xml :作用于整个tomcat中所有的应用

<session-config>
    	<!-- 单位:分钟 -->
        <session-timeout>30</session-timeout>
</session-config>

2.修改当前web应用的web.xml: 作用于当前web应用

<session-config>
    	<!-- 单位:分钟 -->
        <session-timeout>10</session-timeout>
</session-config>

3.修改某一个session的存活时长:只作用于特定的session对象

HttpSession session = req.getSession();
session.setMaxInActiveInterval(60);//单位秒

4.5 session对象的销毁

  1. 自然死亡:距最近调用时间超过设置值

  2. 主动消亡:session.invalidate();

4.6 Session的典型应用

强制登录

LoginController

@WebServlet("/login")
public class LoginController extends HttpServlet{
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1 收参
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String pwd = req.getParameter("pwd");

        //2 调用业务层方法
        //3 跳转
        UserService userService = new UserServiceImpl();
        if(userService.login(username,pwd)){
            HttpSession session = req.getSession();
            session.setAttribute("login",true);
            resp.sendRedirect("/servlet-day02/person/showPersons");
            return;
        }

        resp.sendRedirect("/servlet-day02/login.html");
    }
}

ShowAllPersonsController

@WebServlet("/person/showPersons")
public class ShowPersonsController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 强制登录判断
        HttpSession session = req.getSession();
        //从作用域中获取登录标识,如果获取不到说明没有登录,则重定向到登录页面
        Object login = session.getAttribute("login");
        if(login == null){
            resp.sendRedirect("/servlet-day02/login.html");
            return;
        }
        // 1 收参(省略)
        //2 调用业务层方法
        PersonService personService = new PersonServiceImpl();
        List<Person> persons = personService.listPersons();

        //借助request作用域传递数据
        req.setAttribute("persons",persons);
        //请求转发到showPersonsView
        req.getRequestDispatcher("/person/showPersonsView").forward(req,resp);

    }
}

5.Session和Cookie的关系

Session和Cookie都可以用来实现跟踪用户状态,而二者是关系的:Session的实现依赖于Cookie。

Session的底层原理:

  1. 当client(浏览器)第1次发起请求并获取session后,服务端在服务器内部创建一个Session对象,并将该session的id以(JSESSIONID=id值)的cookie写回浏览器

  2. 当client(浏览器)二次请求时,会自动携带Cookie(也就是JSESSIONID),服务端根据cookie记录的id值获取相应的Session

6.Cookie与Session的区别

6.1存储位置不同

cookie:是针对每个网站的信息,保存在客户端.

session:是针对每个用户的,Session中主要保存用户的登录信息,保存在服务器端.

6.2存储数据大小不同

cookie:一个 cookie存储的数据不超过4K。

session:session存储在服务器上可以任意存储数据, 无大小限制.

6.3 生命周期不同

cookie:cookie可以主动设置生命周期。还可以通过浏览器工具清除.

session:session的生命周期是间隔的,从创建时开始计时如在30min内没有访问session,那么session生命周期就被销毁。

6.4 数据类型不同

cookie:value只能是字符串类型。

session:value是object类型。

6.5 安全性不同

cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗.

考虑到安全应当使用session。

上一篇:程序员开发利器:Your Commands网站上线


下一篇:【音频可视化】通过canvas绘制音频波形图