关于Servlet会话跟踪的那些事儿
关于servlet会话跟踪,一搜都能搜出很多。我也不免落入俗套,也总结了一把。希望我所总结的知识尽量是知识海洋里的一汪清泉。能帮助到我自己和哪怕一个人,那也是值得的。
故事由来:
我们知道,http协议是个无状态的协议,所谓无状态就是指此时刻我们的状态是保持连接,下一刻我们的状态可能就是断开连接,状态是不稳定的,这就导致很多用户在上网时遇到问题,比如购物,我添加几次商品到购物车,如果没有会话跟踪,那么这些商品是没办法添加到一个购物车中的。再比如登录,每次访问同一个网站时,我每次都要输入用户名和密码,在同一个网站中,每个界面都要输入一次用户名和密码才能继续做其他事情。这就很尴尬了,所以,有会话跟踪技术的机制就诞生了。
故事梗概:
维持会话技术的4大法宝
法宝1:Cookie
cookie在浏览器允许使用的状态下,当客户请求服务器后,服务器会发送一个含有唯一的sessionID的cookie给客户端,并保存到客户端本地,下次客户端再和服务器交互时,通过在request头中加入cookie中的信息,服务器能辨识出客户身份,从而维持会话。
法宝2:隐藏的表单字段
在<input>中添加一个隐藏的字段,比如这样:
<input type="hidden" name="sessionid" value="12345">
那么在提交表单时,会把这个隐藏的名为sessionID的值为12345的域提交在GET或者POST数据中,服务器收到我的请求后,会给一个客户端一个cookie中有
Cookie:JSESSIONID=E6047C8DB41EEA107256ECB443640C49
每次向服务器请求时,就带着我的JSESSIONID,服务器会认识我的JSESSIONID给我发送我需要的请求。
法宝3:URL重写
在每个 URL 末尾追加一些额外的数据来标识 session 会话,服务器会把该 session 会话标识符与已存储的有关 session 会话的数据相关联。session 会话标识符被附加为 sessionid=12345,标识符可被 Web 服务器访问以识别客户端。
介绍完上面3个,下面是隆重登场的主角了。
法宝4:使用HttpSession
每一个事物产生都有它的作用,session也是,session由servlet容器产生,是一种会话跟踪技术,能解决用户在登录或者购物时多页面请求或存储相关用户信息。
比如这么个场景:你在打开淘宝,然后看到个想买的商品后,你点击立即购买,但是这时候会跳到登录那个新的界面,然后你登录之后,什么事都不用做,再次回到那个商品购买界面刷新下,你就发现这时候你再买这个商品就可以了。这就是session的作用。
多说一句:上面说到的cookie,其中就包含有session的ID,session是借助cookie来实现会话跟踪的,所以,如果cookie被删或者禁用的话,session这个会话跟踪技术也就无法使用了。
故事真相:
session的前世今生:
这是后来补的,因为之前对session的理解有偏差,所以这里纠正下。由问答形式给出。
session由谁创建,怎么创建?
session由服务器端创建,创建方式:HttpSession session = request.getSession(true)。
session在哪保存?
session保存在服务器端,session创建好会由Tomcat的StandardManager类将session存储在服务器内存中,也可以持久化到DB,file,redis中。
session既然由服务器创建,那么在Tomcat中如何创建的?
在tomcat服务器中由ManagerBase类提供创建方法:随机数+时间+jvmid。
session有哪些接口?
创建好session后就可以使用session的API了,API在下面给出。
客户端会保存session吗?
客户端(浏览器端)是不会保存session的,session在服务器端保存,客户端只保存一个sessionid到cookie中,而不会保存session。
session最终是怎么销毁的?
通过session.invalidate、超时、关闭服务器中三者之一。单纯关闭浏览器session不会消失,因为session不在浏览器端保存,而在服务器端。
session的API如下:
public Object getAttribute(String name)
该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。
public Enumeration getAttributeNames()
该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。
public long getCreationTime()
该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
public String getId()
该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。
public long getLastAccessedTime()
该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
public int getMaxInactiveInterval()
该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。
public void invalidate()
该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。
public boolean isNew()
如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。
public void removeAttribute(String name)
该方法将从该 session 会话移除指定名称的对象。
public void setAttribute(String name, Object value)
该方法使用指定的名称绑定一个对象到该 session 会话。
public void setMaxInactiveInterval(int interval)
该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。
下面说的是session和session的ID,不同的访问者对不同的session和sessionID,
举例如下,一个test.html,一个testSession.java,一个google chrome,一个火狐浏览器。
test.html文件如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<form action="http://127.0.0.1:8081/HelloServlet/testSession" method="post">
<input type="text" name="username" />
<input type="submit" />
</form>
</body>
</html>
testSession.java文件如下(.java文件使用的是eclipse下创建的servlet文件)
package com.hundsun.vivizhang.servlet; import java.io.IOException; import java.io.PrintWriter;
import java.util.Date; import javax.jws.WebService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; @WebServlet("/testSession")
public class testSession extends HttpServlet{
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public testSession() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Create a session object if it is already not created.
HttpSession session = request.getSession(true);
// Get session creation time.
Date createTime = new Date(session.getCreationTime());
// Get last access time of this web page.
Date lastAccessTime =
new Date(session.getLastAccessedTime()); String title = "Welcome Back to my website";
Integer visitCount = new Integer(0);
String visitCountKey = new String("visitCount");
String userIDKey = new String("userID");
String userID = new String("ABCD"); // Check if this is new comer on your web page.
if (session.isNew()){
title = "Welcome to my website";
session.setAttribute(userIDKey, userID);
} else {
visitCount = (Integer)session.getAttribute(visitCountKey);
visitCount = visitCount + 1;
userID = (String)session.getAttribute(userIDKey);
}
session.setAttribute(visitCountKey, visitCount); // Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter(); String docType =
"<!doctype html public \"-//w3c//dtd html 4.0 " +
"transitional//en\">\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<h2 align=\"center\">Session Infomation</h2>\n" +
"<table border=\"1\" align=\"center\">\n" +
"<tr bgcolor=\"#949494\">\n" +
" <th>Session info</th><th>value</th></tr>\n" +
"<tr>\n" +
" <td>id</td>\n" +
" <td>" + session.getId() + "</td></tr>\n" +
"<tr>\n" +
" <td>Creation Time</td>\n" +
" <td>" + createTime +
" </td></tr>\n" +
"<tr>\n" +
" <td>Time of Last Access</td>\n" +
" <td>" + lastAccessTime +
" </td></tr>\n" +
"<tr>\n" +
" <td>User ID</td>\n" +
" <td>" + userID +
" </td></tr>\n" +
"<tr>\n" +
" <td>Number of visits</td>\n" +
" <td>" + visitCount + "</td></tr>\n" +
"</table>\n" +
"</body></html>");
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
此处不用配置web.xml文件。
实验开始,先清掉浏览器的缓存,然后在浏览器中输入 localhost:8080/HelloServlet/test.html ,我的图中用的是127.0.0.1的环路地址,是一样的哈。
输入完后,打开chrome的F12按键,敲击回车,访问到页面,得到的不含cookie的F12中的截图(图1)是这样的。
图1
然后输入一些信息,点击提交后,F12调试页面是这样的(图2)。
图2
点击提交后跳转到这个界面(图3)
图3
然后就能得到下面的结论:
(1)同一浏览器相同窗口刷新后,访问的是同一sessionID,如图4所示,刷新1次,显示访问次数为2.
(2)同一浏览器不同窗口访问,访问的是同一sessionID,如图4所示,开两个窗口,但是sessionId仍然是E04B...065.
图4
(3)同一浏览器关闭后再次访问也不是同一session,如图5所示,切换到firefox后id和visitCount都不同了。
图5
(4)不同的浏览器访问是不同session和sessionID。如图6所示。
图6
故事总结:
这个故事说的是会话跟踪的技术,以后在使用Servlet时,要学会使用,这是一个非常重要的技术,但是也听到有反对使用cookie的,这些都不是重点,重点是这个技术是现在web开发必不可少的。
关于Servlet会话跟踪的那些事儿的更多相关文章
- Servlet - 会话跟踪
Servlet 标签 : Java与Web 会话跟踪 HTTP本身是"无状态"协议,它不保存连接交互信息,一次响应完成之后即连接断开,下一次请求需要重新建立连接,服务器不记录上次连 ...
- 7、Servlet会话跟踪
一.会话跟踪: 不管操作多少功能,都是与当前登录用户相关的信息,当前的登录用户始终没有改变,也就是用户名和密码都没有丢失.但HTTP协议是一个无状态的协议,当一个客户向服务器发出请求(request) ...
- Servlet会话跟踪和Cookies及HttpSession会话
会话只是指一段指定的时间间隔. 会话跟踪是维护用户状态(数据)的一种方式.它也被称为servlet中的会话管理. Http协议是一个无状态的,所以我们需要使用会话跟踪技术来维护用户状态. 每次用户请求 ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 Session常用方法
● public Object getAttribute(String name) 该方法返回在该session会话中具有指定名称的对象,如果没有指定名称的对象,则返回null. ● public ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 Session技术
Servlet提供了HttpSession接口,该接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式. Servlet容器使用这个接口来创建一个HTTP客户端和HTTP服务器之 ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 Cookie常用方法
以下是在Servlet中操作Cookie时可使用的有用的方法列表 ● public void setDomain(String pattern) 该方法设置cookie适用的域,例如 itxdl.c ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 经典面试题
1.描述Cookie的作用 Cookie是网站保存在浏览器客户端的信息,也就是说保存在访客的机器里的变量,一般随着HTTP头发送到客户端.在Cookie生效之后及失效之前,客户每次发出页面请求的时候, ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 经典案例
案例需求:编写一个servlet,可以向session中存放一个消息,再编写一个servlet可以从session取得session中存放的这个消息. 案例实现: package com.xdl.se ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 Cookie路径问题
操作Cookie时,需要注意路径问题: 设置操作:任何路径都可以设置Cookie,但是有时我们也是用设置进行替换Cookie和删除Cookie(maxAge=0)! 替换:只能由完全相同的路径来操作! ...
随机推荐
- restsharp发送服务端请求回传session
今天工作遇到这样一个场景,我需要获取一个游戏目录列表,这个列表接口在线上已经存在,但是这个接口需要登录认证后才能获取到,所以实现这个功能我打算分两部来做: 1.首先调登录接口,以写上session 2 ...
- 简易版CSS3 Tab菜单 实用的Tab切换
今天我们要来分享一款非常简易而又实用的CSS3 Tab菜单,Tab菜单没有非常华丽的动画,但是代码非常简洁易懂,也可以在大部分场合使用,因此也非常实用,如果你需要加入动画效果,也可以自己方便地修改这款 ...
- HTTP知识填补
1.HTTP协议 HTTP协议是计算机通信的一种协议 流程: 1.http客户端发起请求,例如手机访问baidu.com,创建端口,一般位80 2.http服务器在端口监听客户端请求 3.http接收 ...
- Apache Spark Shark的简介
Shark是构建在Spark和Hive基础之上的数据仓库. 目前,Shark已经完成学术使命,终止开发,但其架构和原理仍具有借鉴意义. 它提供了能够查询Hive中所存储数据的一套SQL接口,兼容现有的 ...
- 成都Uber优步司机奖励政策(3月5日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- Windows 下整理内存工具推荐——cleanmem
---恢复内容开始--- cleanmem 是个不错的内存整理工具,www.xdown.com 下载有便携版提供下载. 软件有pro版和free版,一般情况下,free版够用了,没必要用pro版. p ...
- ocp 1Z0-043 61-130题解析
61. You are working in an online transaction processing (OLTP) environment. You realize that the sal ...
- JSF 2 hidden value example
In JSF, you can use the <h:inputHidden /> tag to render a HTML hidden value field. For example ...
- Flask框架获取用户IP地址的方法
本文实例讲述了python使用Flask框架获取用户IP地址的方法.分享给大家供大家参考.具体如下: 下面的代码包含了html页面和python代码,非常详细,如果你正使用Flask,也可以学习一下最 ...
- Codeforces Round #282 (Div. 1) A. Treasure 水题
A. Treasure Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/494/problem/A ...