JavaWeb——Cookie与Session机制

JavaWeb——Cookie与Session机制

 1、前言

  Cookie与Session机制都是应用于Web开发的会话管理或会话跟踪中。最大的区别是:Cookie客户端(浏览器端)会话技术,而Session服务端会话技术,而。本篇文章将系统的说明Cookie与Session机制及其应用场景。

  既然提到Cookie与Session机制都离不开"会话",那么首先来看一下什么是"会话"。

  会话管理的产生:由于HTTP的无状态性,使得会话管理或者会话跟踪成为Web应用开发一个无法避免的问题。默认情况一下,一个WEB服务器是无法区分一个HTTP请求是否为第一次访问。
  会话:一次会话中包含多次请求和响应
  一次会话:浏览器第一次给服务器发送请求,会话建立,直到有一方断开位置
  会话的功能:在一次会话的范围内的多次请求间共享数据

  现在的JavaWeb项目要再谈及会话,一般就是这两种实现方式

   ● 客户端会话技术:Cookie,将数据保存在客户端(浏览器)
   ● 服务端会话技术:Session,将数据保存在服务器

 2、Cookie

  Cookie:客户端会话技术,将数据保存在客户端(浏览器),Cookies是一个很少的信息片段,可自动地在浏览器和Web服务器间交互,因此Cookies可存储在多个页面间传递信息Cookie作为HTTP header的一部分,其传输由HTTP协议控制,此外,可以控制Cookies的有效时间。浏览器通常支持每个网站高达20个Cookies。

  2.1.Cookie的相关操作

   服务端生成Cookie对象
		Cookie cookie = new Cookie(String name,String value);
   HTTP响应时会服务端会将Cookie对象发送(返回)给浏览器
		response.addCookie(cookie);
   服务端获取Cookie对象,由于Cookie没有提供直接根据name获取Cookie的方法,因此只能获取到所有的Cookie[],再根据name一个一个进行比较,最终找出该name所对应的value。
		Cookie[] request.getCookies()
		
		// 根据name一个一个进行比较
		Cookie[] cookies = request.getCookies();
		String name = "xxx";
		String value;
		if (cookies != null) {
		    for (Cookie c : cookies) {
		        if (c.getName().equals(name)) {
		            value = c.getValue();
		       }
		   }
		}
   删除Cookie,将name对应的value属性置为空,就相当于是删除,或者将Cookie的存活时间设置为0(Cookie立即过期),也相当于是删除。服务端删除Cookie后需要给浏览器发送Cookie已被删除的结果(resp.addCookie(rmCookie));

)

		// 将value置空
		Cookie rmCookie = new Cookie(name, "");
		// 将存活时间置0
		rmCookie.setMaxAge(0);
		// 向浏览器发送被删除的Cookie
		resp.addCookie(rmCookie);

  2.2.Cookie的实现原理

   Cookie是一段文本信息。客户端第一次请求服务器时,如果服务器需要记录用户状态,就在响应用户请求时发送一段Cookie信息。客户端浏览器保存该Cookie信息,当用户再次访问该网站时,浏览器会把Cookie做为请求信息的一部分提交给服务器。服务器检查Cookie内容,以此来判断用户状态,服务器还会对Cookie信息进行维护,必要时会对Cookie内容进行修改。(更多关于Cookie实现的文字描述请参考:Cookie实现原理)
   只看文字会让人索然无味,因此还是放个图来更清晰的了解Cookie的实现原理。

JavaWeb——Cookie与Session机制_第1张图片

   这张图中就可以看出,Cookie的信息是保存在浏览器端的。

  2.3.Cookie的细节

   2.3.1.服务器一次可不可以向浏览器发送多个Cookie

    可以,创建多个Cookie对象,使用response对象的addCookie()多次发送即可。

在这里插入图片描述

   2.3.2.Cookie的生命周期(在浏览器中能保存多久)

    默认情况下,当浏览器关闭后,Cookie数据被销毁
    设置Cookie声明周期,使Cookie持久化

用Cookie对象调用setMaxAge(int seconds)方法
  正数:将Cookie数据写到硬盘文件中持久化存储,second表示cookie存活时间,单位是秒
  负数:默认值为-1,存在浏览器内存中,浏览器一关闭就销毁Cookie数据
  零:删除Cookie数据

   2.3.3.Cookie的不可跨域名性(Cookie共享问题)

Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。

    Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作 Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名 不一样,因此Google不能操作Baidu的Cookie。
    与之相同的,若在一个Tomcat服务器中部署了多个Web项目,那么在这些项目中Cookie是否共享?

   默认情况下Cookie不能共享
    setPath(String path):设置Cookie的获取范围,默认情况下设置当前项目的虚拟目录,如果要共享,则将path设置为:"/"。

    不同的Tomcat服务器间Cookie共享问题

    setDomain(String path):如果设置一级域名相同,那么多个服务器间Cookie共享

   2.3.4.Cookie对中文的支持

    在Tomcat8之前,Cookie中不能直接存储中文(Cookie中保存中文只能编码。一般使用UTF-8编码即可),在Tomcat8之后,Cookie支持中文数据。

  2.3.Cookie的特点

   ● Cookie存储的数据保存在浏览器中(客户端)
   ● 浏览器对于单个Cookie的大小有限制(一般4K左右,和浏览器有关)以及对同一个域名下的总Cookie数量也有限制(一般20个左右,和浏览器有关)

  2.4.Cookie的作用

   ● Cookie一般用于存储少量的不太敏感的数据
   ● 用户免登录(在不登录的情况下完成服务器对客户端的身份识别,主要作用)

 3、Session

  Session:服务端会话技术,将数据保存在服务器,在一次会话的多次请求间共享数据。
  HttpSession:Servlet对Session机制的一种封装

  3.1.HttpSession的相关操作

   服务端获取Session对象,如果不存在就创建一个
		HttpSession httpSession = request.getSession();
		
		// 方法重载,如果没有,返回null
		HttpSession httpSession = req.getSession(false);
		// 方法重载,如果没有,创建一个
		HttpSession httpSession = req.getSession(true);
   服务端设置Session对象的值,需要注意的是,这里的value是Object类型的,区别于Cookie只能使用String。因此Session可以存储任意类型任意大小的数据。
		httpSession.setAttribute(String name, Object value);
   服务端获取Session对象的内容,比Cookie好在,Session可以通过name直接查找到对应的值。
		Object value = httpSession.getAttribute(String name);

  3.2.HttpSession的实现原理

   所有保存在HttpSession的数据不会被发送到客户端,不同于其它会话管理技术, Servlet容器为每个 HttpSession生成唯一的标识, 并将该标识发送给浏览器,或创建一个名为JSESSIONID的cookie, 或者在 URL后附加一个名为jsessionid 的参数。 在后续的请求中,浏览器会将标识提交给服务端,这样服务器就可以识别该请求是由哪个用户发起的。 Servlet容器会自动选择一种方式传递会话标识,无须开发人员介入 。
   与Cookie相同,只用文字描述会让人有种想撞墙的想法,因此也放个图了解一下HttpSession的实现原理。

JavaWeb——Cookie与Session机制_第2张图片

  3.3.Session的细节

   3.3.1.当客户端关闭后,服务器不关闭,两次获取Session是否为同一个

    ● 默认情况下,不是同一个
    ● 若想要实现相同,则需要自行创建一个Cookie,该Cookie的name为JSESSIONID(name必须是这个),value为session.getId(),并设置该Cookie的最大存活时间,使得Cookie持久化保存。(虽然session默认生成的Cookie随着浏览器的关闭而销毁,但通过自定义相同的JSESSIONID,从而实现两次访问相同的session,至少,这两次访问是在session还未过期时,若session已过期,就不能实现相同了)
		//希望客户端关闭后再次获取Session能相同
        Cookie cookie = new Cookie("JSESSIONID",session.getId());
        cookie.setMaxAge(60 * 60);
        response.addCookie(cookie);

   3.3.2.客户端不关闭,服务器关闭后,两次获取的Session是否为同一个

    ● 默认情况下,不是同一个
    ● 要确保数据不丢失(session的钝化和活化——Tomcat已经完成了钝化和活化工作,具体钝化活化细节请参考:Session的活化与钝化)

      ● session的钝化:当服务器正常关闭时,还存活着的session(在设置时间内没有销毁) 会随着服务器的关闭被以文件(“SESSIONS.ser”)的形式存储在tomcat 的work 目录下。
      ● session的活化:当服务器再次正常开启时,服务器会找到之前的“SESSIONS.ser” 文件,从中恢复之前保存起来的Session 对象。
      ● 想要随着Session 被钝化、活化的对象它的类必须实现Serializable 接口
      ● I注意:DEA可以完成钝化但是无法活化成功,要依靠本地的Tomcat服务器去完成钝化和活化,但是实际开发中也不会在IDEA里面部署项目,所以关系不大。

   3.3.3.HttpSession的生命周期(Session什么时候被销毁)

    ● 默认情况下是30分钟(容器的配置),可修改Tomcat容器的默认配置(具体操作如下)

JavaWeb——Cookie与Session机制_第3张图片
JavaWeb——Cookie与Session机制_第4张图片

    ● 手动设置当前程序session的过期时间
		// 1、web.xml配置文件中更改配置信息
		
			 20
		
		// 2、调用setMaxInactiveInterval()方法,在用户30分钟之内无活动,设置过期,单位秒
		httpSession.setMaxInactiveInterval(60 * 30);
    ● 手动设置session立即过期(一般用于用户退出登录时,代码中人为设置过期)
		httpSession.invalidate();
    ● 当服务器关闭时,session被销毁(可能牵扯钝化活化问题)

  3.3.Session的特点

   ● Session存储的数据保存在服务器端(一次会话的多次请求的数据)
   ● Session可以存储任意类型任意大小的数据(value为Object)
   ● 不同于URL重新、 隐藏域或cookie, 放入 到HttpSession 的值, 是存储在内存中的, 因此,不要往HttpSession放入太多对象或大对象。 尽管现代的 Servlet容器在内存不够用的时候会将保存在 HttpSessions的对象转储到二级存储上, 但这样有性能问题, 因此需要小心存储。
   ● 放到HttpSession的值是Object类型
     ①可以是任意实现 java.io.Serializable 的java对象,因为Servlet容器认为必要时会将这些对象放入文件或数据库中,尤其在内存不够用的时候。
     ②当然也可以将不支持序列化的对象放入HttpSession, 但是这样的话,当Servlet容器视图序列化的时候会失败并报错。

 4、Cookie与Session的区别JavaWeb——Cookie与Session机制_第5张图片

   参考文档:Cookie与Session(会话技术)、Cookie客户端技术和Session服务端技术。

你可能感兴趣的:(JavaWeb)