【什么是Session?】
Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。
【为何用Session?】
Session技术是为何出现的?这是因为目前网络中所使用的http协议是一种无状态的协议,简单来说就是当你向服务器发送一次请求,然后再一次发送请求到服务端,对于服务器来讲,它是不知道你的第一次请求和第二次请求是来源于同一个人或者说是同一个客户端。这样的话就使我们的客户端和服务端的交互非常的麻烦,就好比是我们每一个人都没有了记忆,你刚对一个人介绍完自己,当你再次和那个人交谈,他依然会问:Who are you?
而Session技术就很好的解决了这个问题,如果没有Session,举个简单的例子:当你在一个页面提交请求数据,页面跳转之后,下一个页面就不能获得你上个页面的请求数据。
关于Session的原理,我从网上找了一张图,相信可以更好的帮助大家理解到底Session是如何工作的,来保证在一个会话中共享数据。如下图所示:
【怎么用Session?】
Session在网络编程中应用广泛,比如我们在登陆各种网站的时候需要填写的验证码,在各大电商网站中购物时的那个购物车等等,都是Session技术的应用场景。下面我就举一个大家都很熟悉的购物车的示例,一起来看看Session如何用在我们的项目开发中,当然这些都是比较简单的demo,仅作参考,不是大型网站购物车的实现方法,切记。
既然我们要做购物车的demo,那么需要建立两个页面,一个商品列表页和一个购物车的页面,然后创建一个Servlet用来处理前台页面的请求,就这么简单。来看具体的代码:
处理请求的Servlet类CServlet:
public class CServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1 获得 用户想要添加的商品信息
String name = request.getParameter("name");//0
//将提交的商品编号翻译成商品的中文名称
String[] products = new String[]{"肥皂","蜡烛","床单","摄影机","内衣","袜子"};
String productName = products[Integer.parseInt(name)]; //最终用户要添加的商品名称
//2 获得session
HttpSession session = request.getSession();
//3 从session取得保存购物车信息的map
Map<String,Integer> cart = (Map<String, Integer>) session.getAttribute("cart");
if(cart !=null){
//取到 ==> 不是第一次添加 ==>继续添加
Integer count = cart.get(productName);
if(count!=null){
cart.put(productName,count+1);
}else{
cart.put(productName,1);
}
}else{
//没取到 ==> 第一次添加 ==> 创建出map添加
cart = new LinkedHashMap<String, Integer>();
cart.put(productName,1);
}
//4将map重新放回session域
session.setAttribute("cart", cart);
//5页面重定向到列表页面继续购物
response.sendRedirect(request.getContextPath()+"/shopping/list.jsp");
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
}
商品列表页list.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>商品列表</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<a href="/day11-session/shopping/cart.jsp" >查看购物车</a>
<table border="1" align="center" >
<tr>
<td>
<h3>肥皂</h3>
<img src="/day11-session/img/haha (1).jpg" width="100" height="100" /><br/>
<a href="/day11-session/CServlet?name=0">加入购物车</a>
</td>
<td>
<h3>蜡烛</h3>
<img src="/day11-session/img/haha (2).jpg" width="100" height="100" /><br/>
<a href="/day11-session/CServlet?name=1">加入购物车</a>
</td>
</tr>
<tr>
<td>
<h3>床单</h3>
<img src="/day11-session/img/haha (3).jpg" width="100" height="100" /><br/>
<a href="/day11-session/CServlet?name=2">加入购物车</a>
</td>
<td>
<h3>摄像机</h3>
<img src="/day11-session/img/haha (4).jpg" width="100" height="100" /><br/>
<a href="/day11-session/CServlet?name=3">加入购物车</a>
</td>
</tr>
<tr>
<td>
<h3>内衣</h3>
<img src="/day11-session/img/haha (5).jpg" width="100" height="100" /><br/>
<a href="/day11-session/CServlet?name=4">加入购物车</a>
</td>
<td>
<h3>袜子</h3>
<img src="/day11-session/img/haha (6).jpg" width="100" height="100" /><br/>
<a href="/day11-session/CServlet?name=5">加入购物车</a>
</td>
</tr>
</table>
<a href="/day11-session/shopping/cart.jsp">查看购物车</a>
</body>
</html>
购物车页面cart.jsp
<%@page import="java.util.Map.Entry"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>购物车</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
//1 获得session
//HttpSession session = request.getSession();
//2 从session中取得 保存购物车信息的map
Map<String,Integer> cart = (Map<String,Integer>)session.getAttribute("cart");
//3 遍历map 在页面上显示
%>
<table border="1" align="center">
<tr><th>商品名称</th><th>商品数量</th></tr>
<%
for(Entry<String,Integer> en : cart.entrySet()){
%>
<tr><td><%=en.getKey()%></td><td><%=en.getValue() %></td></tr>
<%
}
%>
</table>
<a href="/day11-session/shopping/list.jsp">继续购物</a>
</body>
</html>
运行程序我们随便选几样商品来看看是否能够满足我们的需求,如下图所示:
小结一下:
谈到Session,就不得不说cookie,因为Session的一些必要信息是存放在cookie中的,比如最为重要的session_id,可能在某些情况下,Session是必须依赖于cookie才可以发挥其作用的。当然如果禁用了浏览器的cookie时,我们还是可以通过URL来将SessionID传给服务器的。那么Session和Cookie具体有哪些区别呢?
1首先需要大家明白的是,cookie信息是存放在客户的浏览器上的,而Session数据是存放在服务器上的。
2相比较Session来讲,cookie是很不安全的,高手可以通过分析存放在本地的cookie信息并且利用cookie欺骗跳过浏览器,直接对通讯数据进行改写,而Session的安全性相对高些,对于一些敏感信息,最好使用Session。
3Session会在一定时间内保存在服务器上,当访问量剧增的时候,服务器的性能将会大打折扣,此时使用cookie则可以减轻服务器的压力。
4单个cookie保存的数据不能超过4k,而且很多浏览器都会限制一个站点保存的cookie数量,因此大量的数据使用Session比较好。