WEB核心之会话技术

Cookie&Session会话技术

1 会话技术简介

  Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并不知道该客户端是谁,所以需要会话技术识别客户端的状态。会话技术是帮助服务器记住客户端状态(区分客户端)。

  什么是会话?
  从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,成为一次会话。会话技术就是记录这次会话中客户端的状态与数据的。

会话技术分为Cookie和Session:

  • Cookie数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端可以清除cookie。
  • Session将数据存储到服务器端,安全性相对好,但是会增加服务器的压力。

2 Cookie技术

  当用户通过浏览器访问Web服务器,服务器会给客户端发送一些信息,这些信息都会保存在Cookie中。这样,当该浏览器再次访问服务器时,都会在请求头中将Cookie发送给服务器,方便服务器对浏览器做出正确的响应。

  服务器向客户端发送Cookie时,会在HTTP响应头字段中增加Set-Cookie响应头字段。Set-Cookie头字段中设置的Cookie遵循一定的语法格式,具体示例如下:

Set-Cookie: user=tom; Path=/;

  在上述示例,user表示Cookie的名称,tom表示Cookie的值,Path表示Cookie的属性。需要注意的是,Cookie必以键值对的形式存在,其属性可以有多个,但这些属性之间必须用分号和空格分开。


Cookie在浏览器和服务器之间的传输过程


  当用户第一次访问服务器时,服务器会在响应消息中增加Set-Cookie头字段,将用户信息以Cookie的形式发送给浏览器。一旦用户浏览器接收了服务器发送的Cookie信息,就会将它保存在浏览器的缓冲区中,这样,当浏览器后续访问该服务器,都会在请求消息中将用户信息以Cookie的形式发送给Web服务器,从而使服务器端分辨出当前请求是由哪个用户发出的。

  sun公司针对Cookie有个规范,我们先看下原文,

The servlet sends cookies to the browser by using the HttpServletResponse.addCookie(javax.servlet.http.Cookie) method, which adds fields to HTTP response headers to send cookies to the browser, one at a time. The browser is expected to support 20 cookies for each Web server, 300 cookies total, and may limit cookie size to 4 KB each.

  我们主要看最后一句话,它表示每个服务应用(网站)应该支持20个Cookie,总共300个Cookie,还需要限制Cookie的大小在4kb内。当然这仅仅是sun公司提出的规范,我们尽量满足即可。

2.1 服务器端发送Cookie到客户端的API

  1. 创建Cookie
Cookie cookie = new Cookie(String name,String value)

示例:

Cookie cookie = new Cookie("username""zhangsan");`

那么该cookie会以响应头的形式发送给客户端:set-Cookie:name=zhangsan

  1. 设置Cookie在客户端的持久化时间
cookie.setMaxAge(int seconds);

  注意:如果不设置持久化时间,Cookie会存储在浏览器的内存中,浏览器关闭时Cookie信息就会被销毁**(会话级别的Cookie)**。如果设置持久化时间,Cookie信息在设定的时间内会被持久化到浏览器的磁盘文件里,关闭浏览器后下次访问仍可获得该Cookie,直到过期。

示例:

cookie.setMaxAge(10*60);

  设置cookie信息在浏览器的磁盘文件中存储的时间是10分钟,过期浏览器会自动删除该cookie信息。

  1. 设置Cookie的携带路径
cookie.setPath(String path);

  注意:如果不设置携带路径,(默认)那么该cookie信息会在访问产生该cookie的web资源所在的路径都携带cookie信息。

示例:

cookie.setPath("/demo");//代表访demo资源或该路径下的任何资源都携带cookie。
cookie.setPath("/demo/cookieServlet");//代表访问demo中的cookieServlet下的资源才携带cookie信息
cookie.setPath("/");//代表Tomcat下的所有WEB项目都可以访问当前的cookie。
  1. 设置Cookie的有效域
cookie.setDomain(String pattern);

  例如:cookie.setDomain(".baidu.com")则表示此cookie在www.baidu.comwww.zhidao.baidu.com等地址使用。

  1. 向客户端发送Cookie
response.addCookie(Cookie cookie);
  1. 删除客户端的Cookie
cookie.setMaxAge(0);

  如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时间为0的cookie进行覆盖即可,我们可以看成他们同归于尽了。

  例如:假如客户端传过来的Cookie的信息如下

Set-Cookie: name=zhangsan; Max-Age=600; Expires=Wed, 23-Oct-2019 05:04:00 GMT; Path=/demo

  删除此cookie的代码

@WebServlet(urlPatterns="/delete", name="DeleteCookieServlet")
public class DeleteCookieServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建一个名字和客户端的Cookie一样的Cookie,值无所谓了,因为这个cookie自杀式袭击。
        Cookie cookie = new Cookie("name","");
        //设置相同的携带路径,因为我设置客户端的携带路径是项目路径
        cookie.setPath(request.getContextPath());
        //设置Cookie的有效时间
        cookie.setMaxAge(0);
        //发送到客户端:把Cookie发送到客户端,会覆盖掉客户端同name、同path的Cookie
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

2.2 服务器端接收客户端发送来的Cookie

  cookie是以请求头的方式发送到服务器端的

//获得客户端发送过来的所有的Cookie
Cookie[] cookies = request.getCookies();
//遍历数组,通过Cookie的名称获取我们想要的cookie
if (cookies != null && cookies.length > 0) {
	for (Cookie cookie : cookies) {
		if(Objects.equals(cookie.getName(),"我们想要的cookie的名称")){
			String cookieValue = cookie.getValue();
		}
	}
}

2.3 Cookie的一些需要注意的地方

  • Cookie默认是会话级别的,若不设置有效时间,关闭浏览器后Cookie就被销毁了。
  • 使用setMaxAge()方法时:
    • 传入正值代表过了这个数字的时间后,Cookie就会失效。
    • 传入负值表示关闭浏览器后Cookie就会失效。默认值是-1。
    • 传入0表示销毁该Cookie。
  • Cookie的默认携带路径就是产生该Cookie的资源的路径。假如一个Cookie在/demo/login路径下的servlet资源产生的,那么只要访问该路径下的其他资源都会携带该Cookie。
  • 服务器端接收Cookie只有一个方法,即获得所有的Cookie。
  • Tomcat8之前时,Cookie不能存中文。Tomcat8的Cookie能存中文,但是对于一些特殊符号还是不能存储。
  • Sun公司建议Cookie的大小最好限制4kb以内

3 Session技术

  Session技术是将数据存储在服务器端的技术。当浏览器访问Web服务器时,Servlet容器会为每个客户端都创建一块内存空间存储客户的数据,即创建一个Session对象和ID属性

  当客户端后续访问服务器时,需要每次都携带一个标识ID去服务器中寻找属于自己的内存空间。

  需要注意的是由于客户端需要接收、记录和回送Session对象的ID,因此Session的实现是基于Cookie,Session需要借助于Cookie存储客户的唯一性标识JSESSIONID

3.1 获取Session对象

  Session是与每个请求消息紧密相关的,为此,HttpServletRequest定义了用于获取Session对象的getSession()方法。

public HttpSession getSession();

此方法会获得专属于当前对话的Session对象:

  • 如果服务器端没有该会话的Session对象会创建一个新的Session对象,
  • 如果服务器端有该会话的Session对象就会返回当前存在的Session对象。

  实质就是根据JSESSIONID判断该客户端是否在服务器上已经存在session了,简单来说只有JSESSIONID和对应的session同时存在,我们才能获得旧的Session对象,否则就会创建新的。

3.2 Session常用方法

方法功能描述
String getId()  返回与当前Session对象关联的会话标识号,即JSESSIONID
void invalidate()  强制使Session对象无效,即销毁
void setAttribute(String name ,Object Value)  将一个对象与一个名称关联后存储到当前的HttpSession对象中
String getAttribute()  从当前HTTPSession对象中返回指定名称的属性
void removeAttribute(String name)  从当前HttpSession对象中删除指定名称的属性

3.3 持久化Session

  由于Session是基于Cookie的,所以Session也是默认是会话级别的。因为关闭浏览器后,Cookie就被销毁了,浏览器再次访问服务器时,由于没有Cookie而无法发送上次服务器传过来的JSESSIONID,所以找不到服务器端的Session对象的区域。但是需要注意的是,这个Session对象的区域没有被服务器销毁,只是我们没有对应的JESESSIONID,我们拿不到而已。

注意:Session对象,默认存在30分钟。可以配置时间。

设置持久化Session

//获得Session
HttpSession session = request.getSession();
//获取JSESSIONID的值
String id = session.getId();
//创建一个名称一样的Cookie,覆盖服务器自动创建的Cookie
Cookie cookie = new Cookie("JSESSIONID",id);
//设置持久化时间
cookie.setMaxAge(60*60);
//设置携带路径,此项也是浏览器给设置的,我们和它设置的一样即可
cookie.setPath("/WEB16/");
//发送Cookie
response.addCookie(cookie);

3.4 Session的生命周期

  何时创建:一次会话开始。第一次执行request.getSession()方法时创建。即客户端没有JSESSIONID, 或者服务端没有对应的session对象

  何时销毁:

  • 服务器非正常关闭,session就会销毁。(假如服务器正常关闭,Tomcat会把session对象序列化保存到磁盘文件上,重启Tomcat时,会读取文件反序列化恢复成session对象)
  • session对象过期了。默认30分钟,是在用户最后一次操作网站的时候计时的。
    • 修改超时时间。在web.xml里配置即可。
<session-config>
    <session-timeout>超时时间,单位是分钟</session-timeout>
</session-config>
  • 手动销毁session对象session.invalidate()

session的作用范围是?一次会话期间

  • 只要还能找到原有的session对象,里边的数据就能够获取(仍然可以共享的)
  • 什么情况可能会获取不到session里的数据?
    • session对象销毁了,session里的数据就获取不到了
      • 服务器非正常关闭了
      • 会话超时了
      • session手动销毁了
    • session对象还在,但是JSESSIONID没有了,也找不到session里的数据了
      • 客户端清除缓存了,JSESSIONID丢失了
      • 客户端第一次访问,没有JSESSIONID
      • 换了浏览器,没有原本的JSESSIONID

4 一些问题及总结

  1. 有了Cookie为什么还要Session?

  ①Cookie是有大小和个数限制的,只能存字符串。Session存到服务器端的技术,没有大小和个数的限制,能够存储任意对象。

  ②Cookie是存到客户端的,有一定的安全隐患。Session相对来说安全。

  1. Session的生命周期

创建:第一次执行request.getSession()方法时创建。

销毁:
  ①服务器(非正常)关闭。

  ②Session过期了。Session默认的时间是30分钟。可以使用配置文件设置Session的时间。问题:时间的起算点,何时开始计算30分钟?答案是从不操作服务端的资源开始计时。

  ③使用invalidate()方法强制销毁Session。

  1. 浏览器关闭了,Session就销毁了?

  这是错误的。Session对象是存在于服务器端的,和客户端关闭与否没有关系。Session的销毁有上面的三种情况。

  1. Session的作用范围?

  默认再一次会话中。也就是说,一次会话中任何资源都公用一个Session对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值