玩技术,Geeker
一个原创技术文章分享网站

HTTP Session学习笔记

什么是session?

我们每天都在不经意间和session打交道,对于普通的用户来说,他们可以不关心session这个东西;但是对于一位合格的程序员来说,你不得不懂session。

session是什么?直译就是会话的意思;但是在Web开发中,session代表浏览器与服务器的一次会话过程,这个过程是连续的,也可以时断时续的;通常指从进入系统到退出系统之间所经历的时间。

为什么说我们每天都在和session打交道呢?当你打开浏览器,输入http://www.jellythink.com网址,发起请求时,服务器向你返回响应内容,此时就表示服务器已经为你创建了一个会话;后续再访问http://www.jellythink.com上的其它内容时,都是基于这同一个会话进行的。当你关闭浏览器以后,表示你已经退出系统,本次会话也就结束了。

为什么要用session?

我们每天都在和session打交道,那么为什么要用session呢?由于Web的所使用的HTTP协议是无状态的,每一次请求之间都是彼此独立的。这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为。但是,有的时候,我们需要在两个彼此独立的请求之间共享一些状态,例如我通过淘宝首页发起登录请求,成功登录以后;我再对某个商品的详情页发起请求,那么问题来了,我如何在商品的详情页判断我是否登录了淘宝呢?

虽然登录请求和商品详情页请求是两个彼此独立的请求,但是这两个请求之间需要共享我的登录信息,从而确定我是否已经正确登录,才能在详情页将商品正确的加入到我的购物车中。

综上所述,session就是一种用来在客户端与服务器端之间保持状态的解决方案。每一个不同的用户连接系统将得到不同的Session,也就是说session与用户之间是一种一对一的关系。Session在用户进入网站时由服务器自动产生,并在用户正常离开站点时释放。使用session的好处就在于,可以将很多与用户相关的信息,例如用户的帐号、昵称等保存到session中;利用session,可以跟踪用户在网站上的活动。最重要的是,你在购物时,你中意的东西不会加入到别人的购物车中。

cookie和session的关系

在讨论cookie和session的关系之前,如果你对cookie还不是很熟悉,请先移步《HTTP Cookie学习笔记》。

Cookie机制采用的是在客户端保持状态的方案;而Session机制采用的是在服务器端保持状态的方案。Cookie的作用主要是为了解决HTTP协议无状态的问题,而Session机制则是一种在客户端与服务器之间保持状态的解决方案。

Cookie使用起来很方便,使用cookie也能完成session的工作;但是使用cookie有一个很大的弊端,cookie中的所有数据在客户端可以被修改,数据非常容易被伪造,那么一些重要的数据就不能存放在cookie中了,而且如果cookie中数据字段太多会影响传输效率。为了解决这些问题,我们就需要使用session了,session中的数据是保留在服务器端的,相对来说更安全,同时也没有客户端到服务器端这个传输的问题。

当用户访问到一个服务器,服务器就要为该用户创建一个session,在创建这个session的时候,服务器首先检查这个用户发来的请求里是否包含了一个SessionID,如果包含了一个SessionID则说明之前该用户已经登陆过并为此用户创建过session,那服务器就按照这个SessionID从内存中找到对应的session;如果客户端请求里不包含有SessionID,则为该客户端创建一个session并生成一个与此session相关的SessionID。这个SessionID是唯一的、不重复的、不容易找到规律的字符串,这个SessionID将在本次响应中返回到客户端保存,而保存这个SessionID的正是cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。

从上面可以看出,没有了session,cookie依然可以玩的好好的;但是如果没有cookie的支持,session就不能愉快的玩耍了;session需要一种能够在客户端和服务器之间进行交互时,传递SessionID的机制,我们一般都是使用cookie来完成传递SessionID的任务,但是还有一种叫做URL重写的东西,也能完成这个任务。

session的生与死

下面就结合JSP来对session的运行机制做一个简单的分析。

之前的文章我也总结过,在JSP中的九大内置对象中,也包含一个内置的session对象,具体可以参见这篇《JSP内置对象——session对象》。由于JSP是一个特殊的Servlet,当编译JSP的时候,JSP代码则会被转成Servlet对应的Java代码,其中存在这样一句创建session的代码:

session = pageContext.getSession();

这就涉及到到底何时调用这句代码创建session呢?如果JSP没有显示的使用<%@page Session=”false”%>关闭Session,那么就直到server端程序调用HttpServletRequest.getSession()这样的语句时才被创建。由于Session会消耗内存资源,因此,如果不打算使用Session,应该在所有的JSP中关闭它。

既然说到了创建,那就有删除了。在下面几种情况下,会删除session:

  • 程序调用HttpSession.invalidate()
    我们可以通过手动调用HttpSession.invalidate()将一个活动的session置为无效。
  • 距离上一次收到客户端发送的SessionID时间间隔超过了Session的超时设置
    每一个Session都有一个失效时间,默认为30分钟;如果超过了该时间,session将会自动失效;当客户端再次发起请求时,将会得到一个新的Session。我们通过调用setMaxInactiveInterval(int interval)函数修改这个失效时间。
  • 服务器进程被停止(非持久Session)
    一般情况下,为了效率,都是将Session数据保存在内存中的,如果服务器进程被停止了,也就所有的Session信息就丢失了。

这就是session的生命过程。

session共享

如今我们现在使用的大系统,无不是N个小系统组合而成的。比如最简单的公司OA系统,可能由登录系统、签到打卡系统、工时填报系统、合同管理系统等等系统组合而成,这些子系统都是一个个单独的Web应用,由不同的团队开发。那么问题就来了,这么多个子系统之间如何共享Session呢?

我们经常听到单点登录(SSO)这样的词汇。这就是为了解决这样的问题而出来的。用户登录登录验证子系统以后,会生成一个session,用户再登录其它子系统时,虽然是两个不同的Web应用,但是需要共享一个Session,这又是一门非常深奥的学问了。

现在的互联网网站为了提高网站安全性和并发量,服务端的部署的服务器的数量往往是大于或等于两台,多台服务器对外提供的服务是等价的,通过负载均衡进行分配访问,但是不同的服务器上面肯定会有不同的web容器,由上面的讲述我们知道session的实现机制都是web容器里内部机制,这就导致一个web容器里所生成的session的id值是不同的,此时就会出现下面这种现象:

当一个请求到了A服务器,浏览器得到响应后,客户端存下的是A服务器上所生成的session的id;当在另一个请求分发到了B服务器,B服务器上的web容器是不能识别这个session的id值,更不会有这个sessionID所对应记录下来的信息,此时就出现了分歧。这个时候就需要两个不同web容器之间进行session的同步。

这又是一大坨的内容需要去学习。对于这些,我也在路上……,希望各位同仁分享你们的解决方案。

总结

关于Session的知识点有很多,很多,一篇文章不可能总结的完,还有很多我不了解的知识点。在今后的学习过程中,再完善自己对Session的理解与应用。这篇文章权当一个扫盲性质的文章,帮助大家理解Session。

感冒、难受ing…
果冻想-一个原创技术文章分享网站。

2015年12月03日 于呼和浩特。

打赏

未经允许不得转载:果冻想 » HTTP Session学习笔记

分享到:更多 ()

评论 2

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    您好,这句话“没有了session,cookie依然可以玩的好好的;但是如果没有cookie的支持,session就不能愉快的玩耍了”是不是反了?没有cookie,可以通过URL重写发送sessionid保持状态。。。

    chen1年前 (2016-07-30)回复
    • 我在后面说了的,有一种叫做URL重写的东西。

      果冻想1年前 (2016-08-02)回复

在这里玩技术,享受技术带来的疯狂

捐赠名单关于果冻