全屏浏览
缩小浏览
回到页首

web基础---->session的使用

前几天在博问中,看到有人提到了有关session的问题,决定自己整理写一下有关session的原理!说起session,cookie必须是要谈的!

 

目录

  1. Cookie的介绍
  2. Cookie的使用
  3. Session的介绍
  4. Session的使用
  5. Session的原理

 

Cookie的介绍(参照计算机网络)

一、无形之中我们使用的cookie:

使用浏览器浏览网页时,当你要登陆时,网页上有一个记住密码或自动登陆的选项,当你选择时,你就使用了Cookie。那么在下次访问该网站时,你可能就已经自动地登陆了,而不需要从重输入用户名和密码

二、cookie技术的组成
  • 在HTTP响应报文中有一个cookie首部行;
  • 在HTTP请求报文中有一个cookie首部行;
  • 在用户端系统中保留有一个cookie文件,由用户浏览器管理;
  • 在Web站点有一个后端数据库;
三、cookie的工作原理
在了解了cookie技术的组成之后,我们来看看cookie是怎么工作的。下面就以主机A中的浏览器访问网站xxx作为例子来分析cookie的工作原理吧。
 
首 先主机A使用浏览器上网,当主机A第一次访问xxx网站时,当请求报文到达xxx的Web服务器时,该Web服务器将产生一个唯一识别码(例 如:12345),并以此作为索引在它的后端数据库中产生一个表项,并用Set-cookie:首部行和刚才产生的值为设置HTTP响应报文的首部。这样 在HTTP响应报文的首部,我们就可以看到这样的一个首部行——Set-cookie: 12345.
 
当主机A的浏览器收到该HTTP响应报文时,它会看到Set-cookie:首部,然后浏览器在它的本地cookie文件上加入一行,其中包括Set-cookie:首部行中的识别码。
 
由于主机A的cookie文件已经有了用于xxx网站的表项,因此当主机A的浏览器继续浏览xxx网站时,每请求一个Web页面,其浏览器就会 从它的cookie文件中获取到xxx网站的识别码,并放入HTTP请求报文中cookie首部行中,即加入了首部行Cookie: 12345。
 
当xxx网站的服务器收到该包含Cookie首部行的HTTP请求报文后,服务器通过查询后端服务器,确定cookie标识码对应的用户,从而可以直接知道用户的信息(即知道确实有一个这样的用户,不久前登陆过该网站)。
 
注意,在cookie的方式下,xxx网站的服务器可以跟踪主机A在该站点的活动,xxx Web站点并不需要知道主机A的用户是谁,但是,它确切地知道用户12345访问了哪些页面,按照什么顺序,在什么时间。
 
简单点来说,cookie用于标识用户,用户首次访问站点时,可能需要提供一个用户标识,但在后继的访问中,浏览器向服务器传递一个 cookie首部,供服务器识别该用户。因此cookie可以在无状态的HTTP上建立一个用户会话层,允许服务器通过用户与应用程序之间的会话对用户进 行验证。
 

Cookie的使用

 java中的response响应中加入cookie:

Cookie cookie = new Cookie("JSESSIONID", "123456");
cookie.setPath("/test");
response.addCookie(cookie);

 java中的request请求中得到cookie:

Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
    String cookieName = cookie.getName();
    String cookieValue = cookie.getValue();
    System.out.println(cookieName + ", " + cookieValue);
}

 

Session的介绍

1、Session的概念

使用Cookie和附加URL参数都可以将上次请求的状态信息传递到下一次请求中,但是如果传递的状态信息较多,将极大降低网络传输效率和增大服务器端程序处理的难度。Session技术是一种会话状态保存在服务器端的技术,它可以比喻成是医生发给病人的病历卡和医院为每个病人保留的病历档案的结合方式。客户端需要接收、记忆和回送Session的会话标示号,Session可以且通常是借助Cookie来传递会话标示号。

 

2、Session的跟踪会话机制

Servlet API规范中定义了一个HttpSession接口,HttpSession接口定义了各种管理和操作会话状态的方法。HttpSession对象是保持会话状态信息的存储结构,一个客户端在WEB服务器端对应一个各自的HttpSession对象。Web服务器并不会在客户端开始访问它时就创建HttpSession对象,只有客户端访问某个能与客户端开启会话的Servlet程序是,Web应用程序才会创建一个与该客户端对应的HttpSession对象。Web 服务器为HttpSession对象分配一个独一无二的会话标示号,然后在响应消息中将这个会话标示号传递给客户端。客户端需要记住会话标示 号,并在后续的每次访问请求中都把这个会话标示号传送给Web服务器,Web服务器程序依据回传的会话标示号就知道这次请求的客户端发出的,从而选择与之 对应的HttpSession对象。

 

3、Session的跟踪机制

Web 应用程序创建与某个客户端对应的HttpSession对象后,只要没有超出一个限定的空闲时段,HttpSession对象就驻留在Web 服务器内存之中,该客户端此后访问任意的servlet程序时,它们都使用与客户端对应的那个已存在的Httpsession对象。HttpSession 接口中专门定义了一个SetAttribute方法将对象存储到HttpSession对象中,还定义了一个 getAttribute方法来检索存储在Httpsession对象中的对象,存储进Httpsession对象中的对象可以被属于同一个会话的各个请 求的处理程序共享。Session是实现网上商城的购物车的最佳方案,存储在某个客户Session中的一个集合对象就可充当给客户的一个购物车。

 

4、Session的超时管理

Web服务器无法判断当前的客户端浏览器是否还会继续访问,也无法检测客户端浏览器是否关闭,所以,即使客户已经离开或关闭了浏览器,Web服务器还要保留与之对应的Httpsession对象。随着时间的推移而不断增加新的访问客户端,Web服务器内存中将会因此积累起大量的不断不在使用的Httpsession对象,并将最终导致服务器内存耗尽。Web服务器采用“超时限制”的办法来判断客户端是否还在继续访问,如果某个客户端在一定的时间之内没有发出后续请求,Web服务器则认为客户端已经停止了活动,结束与该客户端的会话并将与之对应的Httpsession对象变成垃圾。如果客户端浏览器超时后再发出访问请求,Web服务器则认为这是一个新的会话开始,将为之创新的HttpSession对象和分配新的会话标示号。

 

session的使用

session中存储数据:

String username = request.getParameter("username");
HttpSession session = request.getSession();
System.out.println(session.getId());
session.setAttribute("username", username);

session中得到数据:

HttpSession httpSession =  request.getSession();
String username = (String)httpSession.getAttribute("username");

 

session的原理

我们创建一个项目来分析session的原理:

一、创建一个主页index.jsp

<form action="ContractListServlet" method="get">
    username: <input type="text" name="username"/><br>
    <input type="submit" value="submit">
</form>

清除浏览器所有cookie,访问url:http://localhost:8080/SessionTest/

详细的请求头部:

GET /SessionTest/ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

详细的响应头部:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=5973D26B6164CDDAFF190965C0B4677C; Path=/SessionTest/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 418
Date: Tue, 15 Mar 2016 10:25:12 GMT

保存在浏览器的cookie:

说明:

  • 当我们清除cookie,向tomcat服务器发送请求时,浏览器首先会检查是否存在cookie文件(因为我们已经清除了cookie,所以找不到cookie)。第一次访问,没有cookie,直接发送请求。
  • tomcat服务器发现请求中没有cookie头部,于是为用户创建一个sessionid,用作标识这个用户的会话,并且在返回给用户的响应中增加了cookie的头部信息,该cookie的path为该项目的上下文/SessionTest。
  • 浏览器接收响应,检查响应,发现cookie的头部,把cookie保存起来
  • 当cookie还存在时,(也就是人们常说的再次请求)浏览器检查自身保存的cookie,如果host与path都符合。那么在请求的头部增加该符合的cookie信息
  • tomcat服务器接收到该cookie,得到cookie中的JSESSIONID的值与先前保存的sessionid做比较,如果一致,则服务器视为是同一个会话

 

二、创建ContractListServlet,以响应index.jsp的提交

String username = request.getParameter("username");
HttpSession session = request.getSession();
System.out.println(session.getId());
session.setAttribute("username", username);

Cookie cookie = new Cookie("JSESSIONID", "123456");
cookie.setPath("/test");
response.addCookie(cookie);
request.getRequestDispatcher("/list.jsp").forward(request, response);

填写内容linux,点击提交:url为http://localhost:8080/SessionTest/ContractListServlet?username=linux

详细的请求头部:

GET /SessionTest/ContractListServlet?username=linux HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/SessionTest/
Cookie: JSESSIONID=5973D26B6164CDDAFF190965C0B4677C
Connection: keep-alive

详细的响应头部:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=123456; Path=/test
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 331
Date: Tue, 15 Mar 2016 10:29:25 GMT

保存的cookie:现在有两个了

 

三、 只要我们访问的url是这样的形式http://localhost:8080/cookiePath/xxx/xx,浏览器都会携带cookie信息去发送请求的:

  • localhost是服务器的地 址,
  • 8080是服务器的端口,
  • cookiePath是cookie的path(图片见上),

由于上述我们已经有了两个cookie,它们的path分别为, /test和/SessionTest,于是测试访问url:http://localhost:8080/test/jjii

虽然报错404,但是cookie信息仍旧在请求当中:

GET /test/jjii HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=123456
Connection: keep-alive

 关闭浏览器,cookie被自动清除,所以用户再次的请求,浏览器没有找到cookie,会像上述第一次访问一样,请求中没有cookie的头部。

 

四、 我们改动ContractListServlet的代码,在response中另外再增加两个cookie2:以下是加了之后的代码

Cookie cookie = new Cookie("JSESSIONID", "123456");
cookie.setPath("/test");
Cookie cookie3 = new Cookie("JSESSIONID", "123456");
cookie3.setPath("/SessionTest/");
Cookie cookie2 = new Cookie("df", "456789");
cookie2.setPath("/");

response.addCookie(cookie);
response.addCookie(cookie2);
response.addCookie(cookie3);

 再次访问到从头开始访问到url:http://localhost:8080/SessionTest/ContractDetailServlet

详细的请求头部:

GET /SessionTest/ContractListServlet?username=linux HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/SessionTest/
Cookie: JSESSIONID=3EF72ED7EC55DA676714F773E9110DB9
Connection: keep-alive

 详细的响应头部:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=123456; Path=/test
df=456789; Path=/
JSESSIONID=123456; Path=/SessionTest/
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 321
Date: Tue, 15 Mar 2016 12:04:00 GMT

浏览器中的cookie有三条:

  • name: JSESSIONID, content: 123456, path: /test
  • name: df, content: 456789, path: /
  • name: JSESSIONID, content: 123456, path: /SessionTest/

结果分析:

  • 首先浏览器请求时,会携带cookie头部的:JSESSIONID=5DA63C198B1BBF3930A3CE7EC8613207
  • 然后在返回的时候,在响应头部加了三个cookie信息,由于cookie3的名字与路径都与tomcat服务器默认返回的cookie一致,所以导致了该cookie被代码中的cookie3覆盖

 

五、接着上面的程序,我们添加list.jsp到ContractDetailServlet的请求:http://localhost:8080/SessionTest/ContractDetailServlet

详细的头部请求:

GET /SessionTest/ContractDetailServlet HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/SessionTest/ContractListServlet?username=linux
Cookie: JSESSIONID=123456; df=456789
Connection: keep-alive

详细的头部响应:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=D0ECF2D2EF3946CBBB34BC7E4A426D94; Path=/SessionTest/; HttpOnly
Content-Length: 0
Date: Tue, 15 Mar 2016 12:06:19 GMT

浏览器中的cookie有三条:

  • name: JSESSIONID, content: 123456, path: /test
  • name: df, content: 456789, path: /
  • name: JSESSIONID, content: D0ECF2D2EF3946CBBB34BC7E4A426D94, path: /SessionTest/

结果分析:

  • 首先浏览器找到匹配/SessionTest的cookie,找到了cookie2(path /)与cokie3(path /SessionTest/ ),在请求中加入这两个cookie
  • tomcat服务器接收到请求,发现cookie的sessionid与自身保存的不一致,于是为用户创建了一个sessionid,并把cookie加入到返回的头部
  • 浏览器接收到响应的报文,把cookie保存起来,tomcat服务器发送的cookie覆盖了浏览器原来的cookie3

 

以上是我个人对了session的理解,不正确的地方,还望大家斧正!

posted @ 2016-03-15 20:15  huhx  阅读(7011)  评论(0编辑  收藏  举报