一、会话技术
1. 什么是会话
- 会话的特征
- 会话能够把同一用户发出的不同请求之间关联起来。不同用户的会话应当是相互独立的
- 会话一旦建立就一直存在,直到用户空闲时间超过了某一个时间界限,会话才会中断。 好比大家打电话,超过了某一定时间就会自动断开。
2. 什么是会话技术
3. 会话技术的分类
二、 Cookie
1. 什么是cookie
Cookie 可以翻译为“小甜品,小饼干” , Cookie 实际上是指小量信息,是由 Web 服务器创建的,将信息存储在用户计算机上的文件。当用户通过浏览器访问服务器的时候,浏览器会自动携带早前存储的cookie ,传递给服务器。
2. Cookie的应用场景
商品浏览记录
购物车信息
记住账号密码
...
3. Cookie的基本使用
Cookie cookie = new Cookie("key" ,"value");
response.addCookie(cookie);
4. Cookie的分类
- 临时性Cookie
- 持久性Cookie
5. 获取上次访问时间
- 页面准备
<form action="user_login" method="post">
用户名:<input type="text" name="username"/></br>
密 码:<input type="password" name="password"/></br>
<input type="submit" value="登录"/>
</form>
- controller
@RestController
public class UserController {
private static final String TAG = "UserController";
@RequestMapping("user_login")
public String login(HttpServletRequest request , HttpServletResponse response , String username , String password){
System.out.println(username + " : " + password);
HttpSession session = request.getSession();
// session.setAttribute("name","zhangsan");
String id = session.getId();
System.out.println("id=" + id);
//1. 判断账号密码
if("admin".equals(username) && "123".equals(password)){
String result = "欢迎您 , "+ username;
//2.要获取cookies
Cookie[] cookies = request.getCookies();
//有cookie
if(cookies != null){
//就想看cookie里面有没有带上次的时间
for(Cookie cookie : cookies){
//如果能成立,就表示找到了上一次访问的时间。
if("last".equals(cookie.getName())){
long time = Long.parseLong(cookie.getValue());
Date date = new Date();
date.setTime(time);
result += "\r\n 上一次访问时间是:"+date.toLocaleString();
}
}
}
//只要有登录成功,就必须返回最新的登录时间。
String time = System.currentTimeMillis()+"";
Cookie cookie = new Cookie("last" , time);
cookie.setMaxAge(60*60*24*7);
response.addCookie(cookie);
return result;
}
return "登录失败";
}
}
6. Cookie的问题
- cookie 大小有限制,每个服务器在最多不能超过20个。
- cookie 是存放在客户端上,信息不安全,有被截获的可能
三、 Session
1. 什么是session
2. Cookie 和 Session的对比
cookie
数据存放在客户端
数据不安全
减轻服务器压力, 用户磁盘占用比较多。
存放的数据有限
session
数据存放在服务器端
数据相对比较安全。
服务器压力大一点。
存放的数据 依赖服务器的内存空间。
3. Session的简单使用
获取session
HttpSession session = request.getSession()
存值
session.setAttribute(name ,value);
取值:
session.getAttribute(name);
移除值
session.removeAttribute(name);
让session失效 作废
session.invalidate();
获取id值
session的id值就是这一块内存空间的唯一标识符。 session.getId() .
4. Session的背后细节
- 第一次访问
- 第二次访问
5. session 销毁的细节!
- 销毁session
- invaidate()
- 自动失效。 有效期。 默认30分钟
6. Session的作用范围 & 生命周期
作用范围
生命周期
第一次调用request.getSession()就创建。
关闭服务器 session超时了。默认30分钟。 从最后一次请求开始计时。 调用invalidate . 让空间失效、作废
7. 购物车案例
- 准备工作
compile("org.thymeleaf:thymeleaf-spring4:2.1.4.RELEASE")
- 在模板页面上,要记得引入命名空间
<html xmlns:th="http://www.thymeleaf.org" >
1. 显示商品列表
- index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2><a href="list">开始购物</a></h2>
</body>
</html>
- 商品实体类
public class Product {
private int id; // 商品的编号
private String name; //商品名字
private double price ; //商品价格
get & set 方法
...
}
- 商品controller
@Controller
public class ProductController {
private static final String TAG = "ProductController";
//准备商品数据
private static List<Product> list;
static{
list = new ArrayList<Product>();
list.add(new Product(1,"iphone6s" ,3788));
list.add(new Product(2,"小米8" ,2788));
list.add(new Product(3,"vivo20" ,4788));
list.add(new Product(4,"meizu6" ,3690));
list.add(new Product(5,"诺基亚200" ,188));
}
@RequestMapping("list")
public ModelAndView list(){
//1. 构建商品集合
//2. 存储数据到model
ModelAndView modelAndView =new ModelAndView();
//设置模型数据
modelAndView.addObject("list" , list);
//设置跳转的目标是哪里。 list.html
modelAndView.setViewName("list");
return modelAndView;
}
}
- 商品列表 list.html 位于 /resources/templates/下
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="UTF-8"/>
<title>商品列表页面</title>
</head>
<body>
<h2>商品列表</h2><br/>
<table>
<thead>
<td width="100px">编号</td>
<td width="100px">名称</td>
<td width="100px">价格</td>
<td width="100px">操作</td>
</thead>
<!--从这里开始就是真正的商品数据显示了
p 遍历 list集合的出来的每一个元素对象, 其实好就是商品对象。
aa: 表示遍历的状态信息
${aa.index} :遍历的索引
-->
<tr th:each="p,status:${list}">
<td th:text="${p.id}">100</td>
<td th:text="${p.name}">苹果笔记本</td>
<td th:text="${p.price}">9999</td>
<!--<td ><a href="addToCart?index=1">加入购物车</a></td>-->
<td ><a th:href="@{addToCart(index=${status.index})}">加入购物车</a></td>
</tr>
</table>
</body>
</html>
2. 加入购物车
- 添加购物车方法
//添加商品到购物车, 现在拿到的是商品的索引
@RequestMapping("addToCart")
public String addToCart(HttpServletRequest request , int index){
System.out.println("要添加商品到购物车了~");
HttpSession session = request.getSession();
//1. 根据索引,获取到要添加到购物车的商品
Product product = list.get(index);
//2. 加入购物车 购物车其实就是商品和数量的对应关系。
Map<Product , Integer> map = (Map<Product , Integer>)session.getAttribute("cartMap");
//第一次来,连购物车都没有
if(map == null){
map = new HashMap<Product , Integer>();
}
//判断购物车里面是否有该商品 ,如果有 数量 + 1 ,如果没有,数量-1
if(map.containsKey(product)){
map.put(product , map.get(product) +1 );
}else{
map.put(product , 1 );
}
//3. 存储到session中。
request.getSession().setAttribute("cartMap" , map);
//当前的跳转是基于template/list.html ,所以需要重定向跳转到中转页面
return "redirect:transfer.html";
}
- 中转页面
<body>
<a href="list"><h2>继续购物</h2></a><br>
<a href="toCart"><h2>去购物车查看</h2></a><br>
</body>
3. 显示购物车
- cart.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<h2>购物车列表</h2>
<table>
<thead>
<td width="100px">商品名称</td>
<td width="100px">商品价格</td>
<td width="100px">购买数量</td>
<td width="100px">小计</td>
</thead>
<!--把session里面的购物车拿出来遍历显示。 购物车是一个map集合
map集合的遍历出来,其实就是一个key 和 一个value 的组合 。
这种组合entry
m就是entry
map<Product , Integer>
-->
<tbody>
<tr th:each="m:${session.cartMap}">
<td th:text="${m.key.name}">联想鼠标垫</td>
<td th:text="${m.key.price}">10.0</td>
<td th:text="${m.value}">1</td>
<td th:text="${m.key.price * m.value}">1</td>
</tr>
</tbody>
</table>
</body>
</html>