全部章节 >>>>
本章目录
8.1 Session机制
8.1.1 Session 简介
- Session 是服务器端记录客户端信息的机制,比 Cookie 更为简单安全,但是增加了服务器的内存压力,是使用最为普遍的一种会话跟踪技术
- Cookie虽然也可以存储用户信息,和Session最大区别在于:Cookie 保存在客户端浏览器中(不安全),而 Session 保存在服务器中
Session 识别:
- 当客户端访问某个编写了创建 HttpSession 实例代码的 Servlet 时,才会创建一个 HttpSession 实例,并为其分配一个独一无二的会话 ID,将ID以 Cookie 的方式传递给客户端
- 客户端需要记住此会话ID,并在后续每次请求时将此会话 ID 回传给 Web 服务器,Web 服务器程序会根据回传的会话 ID,找到对应的HttpSession 实例
- HttpSession 实例中存放对象数据,也可以随时从 HttpSession 实例中取出对象数据或移除对象数据
8.1.2 创建 HttpSession 实例
HttpServletRequest 接口中提供了两个方法来创建 HttpSession 实例
方法名 |
作用 |
public HttpSession getSession() |
服务器判断当前请求是否已存在会话,如果存在则返回匹配的会话实例;不存在则创建一个新会话实例,并且分配唯一SessinID |
pulbic HttpSession getSession(boolean flag) |
flag 用于指定是否有必要创建一个新的会话,为false时 ,如果客户端先前没有建立会话,则此方法返回 null |
示例:
HttpSession session = request.getSession();
从request对象中获取session对象
8.1.3 HttpSesison 的常用方法
HttpSession 接口中常用方法如下
方法名 |
作用 |
void setAttribute(String name,Object value) |
用于以键值对形式向session中存入数据 |
Object getAttribute(String name) |
用于从session中获取指定键的值 |
void removeAttribute(String name) |
根据键从session中移除某个数据 |
String getId() |
用于获取 session对象的ID |
boolean isNew() |
判断当前会话是否是新建的会话 |
void invalidate() |
使当前 Session 失效,如退出登录时调用 |
public void setMaxInactiveInterval(int seconds) |
设置 Session 的有效时间,单位为秒 |
int getMaxInactiveInterval() |
获取Session 的有效时间,单位为秒 |
示例:使用Session常用方法存取数据
Date createTime = new Date(session.getCreationTime());
Date lastAccessTime = new Date(session.getLastAccessedTime());
if (session.isNew()) {
title = "Welcome to my website";//判断session是否是新的会话,如果是则存入数据
session.setAttribute(userIDKey, userID);
session.setAttribute(visitCountKey, visitCount);
}
visitCount = (Integer) session.getAttribute(visitCountKey);//取出session中的数据
userID = (String) session.getAttribute(userIDKey);
session.setAttribute(visitCountKey, visitCount);
8.1.4 Session 的有效期
session是服务端开辟存储客户端会话数据的内存空间,随着访问人数越多, session也会越多,而服务端并不知道客户端何时关闭浏览器结束会话,所以session引入了默认超时时间30分钟
- 可以在代码中通过设置maxInactiveInterval属性调整超时时间(秒)
- 可以在tomcat安装目录下web.xml中修改配置文件设置全局超时时间(分钟)
8.1.5 Session 与 Cookie 比较
- Session和Cookie都可以存储客户端数据,其区别如下:
- 存取方式上有不同:session可以存储任何数据类型,cookie只能存储字符串
- 存储有效期时间有不同:session服务端决定时间,cookie则是浏览器
- 对服务器造成的负担不同:session存在服务端,对服务器影响大;cookie则是客户端上
- 浏览器支持有不同:cookie需要客户端浏览器支持 安全性上有不同:cookie存储在客户端,有安全性隐患
8.1.6 实践练习
8.2 URL 重写技术
8.2.1 URL 重写技术概述
Cookie 被证明存在安全隐患,因此一些谨慎的用户都会在浏览器中设置禁用 Cookie,如下IE浏览器设置
浏览器禁用Cookie后,session将无法正常使用
如何解决禁用Cookie后的问题?
可以使用 URL 重写机制跟踪用户会话:
- URL 重写技术会在 URL 请求中嵌入标识客户的 SessionID,使用 Servlet 容器解释 URL 并取出 SessionID,根据 SessionID 将请求与特定的 Session 关联
8.2.2 URL 重写技术原理
HttpServletResponse 接口定义两个用于自动完成 URL 重写的方法:
- public String encodeURL(String url),用于自动重写超链接和 form 表单的 action 属性的 URL
- public String encodeRedirectURL(String url),用于自动重写要传递给 HttpServletResponse 接口中的sendRedirect() 方法的 URL
两个方法首先会判断客户请求消息中是否包含 Cookie 字段,如果没有则表示客户端不支持 Cookie,它将把会话ID 作为 JSESSIONID 参数值连接到 URL 末尾,如果有则不会附加 JSESSIONID 参数值。
示例:禁用Cookie后,使用URL重写保持sessionID以识别同一会话
PrintWriter pw=response.getWriter();
pw.println("<title> 未使用 URL 重写 </title>");
pw.println("<a href='"+response.encodeURL("CreateSessionServlet")+"'> 点击后
跳转至 CreateSessionServlet</a>");
pw.close();
使用URL重写将sessionID跟在URL后面
8.2.3 实践练习
8.3 综合应用——购物车系统(一)
8.3.1 购物车系统概述
购物车系统(E-Shopping Cart System)是电子商务系统中非常关键的一个功能模块,如网上购物系统、网络购物系统和网上开店系统等,实质上都是一样,就是程序结合数据库开发的网站系统
购物车系统中,用户浏览商品后将选中的商品放入购物车中,可以随意切换至其他界面,不同用户不同购物车中商品可以随时查看和移除,并且能在最终结账产生订单
8.3.1 表购物车系统的功能模块
一般的购物车系统集成了产品发布与查询、会员注册登录、购物车、在线订单、在线支付和在线交流等完善的网上销售功能,最主要的是管理员只需要登录网站后台管理就可以在线发布商品、处理订单,完全不需要任何网站建设的知识
购物车系统中首先必须有商品的列表展示功能,用户选择商品后,可以放入购物车,购物车模块中需要提供如下功能
- 加入购物车
- 查看购物车
- 购物车中商品移除
- 清空购物车
- 提交购物车结算
8.3.2 实践练习
8.4 综合应用——购物车系统(二)
8.4.1 购物车的发展趋势
商务网站的购物车系统功能:
- 包含用户登录界面
- 用户进行登录后,可以完成查看产品类型,查看购物车内容、订购产品、显示订购单和删除指定订单等相应功能
- 若成功订购,还可以按照网页指示用银行划拨或信用卡方式进行支付
8.4.1 购物车的实现
购物车实际就是一个存放用户选中商品的容器,需要考虑以下几个问题:
- 区分不同用户,不同用户选择的商品归属用户自己
- 跨越多个不同界面有效,用户经常来回商品、搜索、购物车不同的界面
将购物车中的商品信息存放在Session中是非常适合的,session可以区分不同的客户端,还能跨越多个界面存储数据
购物车中需要存放多个商品信息,以什么形式存储这些商品更为方便放入、移除、累加?
用户可以选择多个不同的商品放入购物车,可以使用List或者Map均可以实现购物车中已选商品信息的存储
示例:添加数据到购物车
public void addCar(HttpServletRequest request, HttpServletResponse response) {
// 获取 Session 对象中已存在的购物车信息
HttpSession session = request.getSession();
List<Shopping> carShoppingList = (List<Shopping>) session.getAttribute("scl");
if (carShoppingList == null) {
carShoppingList = new ArrayList<Shopping>();
}
// 获取提交选中要放入购物车的商品信息数组
String[] goods = request.getParameterValues("goods");
for (String good : goods) {
Shopping shopping = new Shopping();
//商品对象信息赋值代码省略
// 将商品添加至 carShoppingList 集合中
carShoppingList.add(shopping);
}
// 将 carShoppingList 保存至 Session 范围内
session.setAttribute("scl", carShoppingList);}
示例:查看购物车
HttpSession session = request.getSession();
// 获取购物车中的商品集合
List<Shopping> shoppingCar = (List<Shopping>) session.getAttribute("scl");
System.out.println(shoppingCar);
if (shoppingCar == null) {
// 购物车中没有商品
request.setAttribute("msg", " 对不起,购物车中没有商品 ");
request.getRequestDispatcher("ShoppingServlet").forward(request, response);
} else {
HashSet<Shopping> shoppingSet = new HashSet<Shopping>(shoppingCar);
// 创建 List 对象用户保存同一商品被放入购物车中的次数
List<Integer> timesList = new ArrayList<Integer>();
for (Shopping shopping : shoppingSet) {
int times = Collections.frequency(shoppingCar, shopping);
timesList.add(times);
}
}
//跳转到显示数据界面
8.4.2 实践练习
总结
- Session是服务端用于保存客户端数据的内容空间,为了区分不同的客户端,每个Session都有唯一的SessionID标识,该ID是以Cookie的形式发给客户端
- 通过HttpServletRequest对象的getSession()方法可以获取Session对象
- 通过调用Session对象的setAttribute和getAttribute可以存入和取出session中的数据
- Cookie是存储在客户端,而Session是存储在服务端
- 客户端禁用Cookie后,可以使用URL重写技术保持sessionID的有效性
- 购物车是电商应用中必不可少的一个功能模块,一般都是以集合的形式存储在Session中