码迷,mamicode.com
首页 > 其他好文 > 详细

cookie和session

时间:2016-03-06 17:04:58      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:

学习目标

  1. cookie技术
  2. session技术
  3. 用户管理应用场景案例

会话及其会话技术:

1、会话

 什么是会话?

  用户打开浏览器,访问一个网站进行一系列操作,关闭浏览器离开,完整过程 就是会话

 会话过程中要解决的一些问题:

  • 每个用户与服务器进行交互的过程中,各自会有一些数据,程序要想办法保存每个用户的数据;
  • 例如:用户点击超链接通过一个servlet购买了一个商品,程序应该保存用户购买的商品,以便用户点击结账servlet时,结账servlet可以得到用户商品为用户结账;
  • 思考:用户购买的商品保存在request或servletContext中行不行?
    不可以,原理分析:
    技术分享

2、cookie技术

 一种将用户信息保存在客户端技术 ,客户端会将cookie信息自动发送给服务器。

  技术分享

 2.1、cookieAPI介绍

  技术分享

  • 代码示例:

     1 import java.io.IOException;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.http.Cookie;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 
     9 public class CookieDemo1 extends HttpServlet {
    10 
    11     public void doGet(HttpServletRequest request, HttpServletResponse response)
    12             throws ServletException, IOException {
    13         doPost(request, response);
    14 
    15     }
    16 
    17     public void doPost(HttpServletRequest request, HttpServletResponse response)
    18             throws ServletException, IOException {
    19         //   开始coding................
    20         /**
    21          * 向浏览器发送cookie 信息 api 演示
    22          */
    23         // 1: 创建一个cookie 对象
    24         // 第一个参数 cookie 名称 第二个参数 保存该cookie 的值 cookie是不能存储中文信息
    25         Cookie cookie = new Cookie("cc", "hellocookieCC");
    26         // 默认cookie 会话结束 cookie 失效 会话机制的cookie
    27         cookie.setMaxAge(3600 * 24 * 7);// 设置浏览器保存cookie 信息的有效时间 持久化cookie
    28         // 2: 发送给浏览器 response 对象发送cookie
    29         // 3: 设置cookie 访问的有效路径
    30         cookie.setPath("/");// cookie 的有效路径 表示 /day11/aa
    31                                     // 下面的所有目录都可以访问该cookie
    32 
    33         // 结论 cookie path 设置 /
    34         // 发送cookie 到 浏览器
    35         response.addCookie(cookie);
    36 
    37     }
    38 
    39 }

  技术分享

 2.2、cookieAPI详解

  • 读取cookie
    request.getCookies() 返回Cookie[]
      首先判断cookies数组是否存在 cookies == null,如果cookies存在,根据cookie的name去查找指定cookie
    代码示例:
     1 import java.io.IOException;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.http.Cookie;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 
     9 public class GetCookie extends HttpServlet {
    10 
    11     public void doGet(HttpServletRequest request, HttpServletResponse response)
    12             throws ServletException, IOException {
    13         doPost(request, response);
    14 
    15     }
    16 
    17     public void doPost(HttpServletRequest request, HttpServletResponse response)
    18             throws ServletException, IOException {
    19         //   开始coding................
    20         /**
    21          * 获取浏览器保存的cookie 信息 浏览器发送 .... 浏览器每次发送请求,都携带cookie信息,这是浏览器本身的机制
    22          */
    23         // 1: 获取cookie信息 ... 对象 request
    24         Cookie[] cookies = request.getCookies();// 获取cookie 数组 空?
    25 
    26         for (Cookie cookie : cookies) {
    27             System.out.println(cookie.getName() + "----" + cookie.getValue()
    28                     + "-----" + cookie.getPath());
    29         }
    30 
    31     }
    32 
    33 }
     1 import javax.servlet.http.Cookie;
     2 
     3 public class CookieUtils {
     4 
     5     public static Cookie getCookie(String name, Cookie[] cookies) {
     6         // 通过cookie name 在所有cookie 返回指定 的cookie
     7         if (cookies == null) {
     8             return null;
     9         } else {
    10             for (Cookie cookie : cookies) {
    11                 if (cookie.getName().equals(name)) {
    12                     return cookie;
    13                 }
    14             }
    15         }
    16         return null;
    17     }
    18 
    19 }
  • 服务器向客户端发送cookie

    cookie对象创建 new Cookie(name,value)

    response.addCookie(cookie) 将cookie发送客户端 保存到浏览器中

    * cookie有name和value

     提供三个方法:getName 获取cookie的名称

                     getValue 获取cookie 的值

                     setValue 设置cookie 的值

  • cookie从持久性上分为两类:会话cookie持久cookie

    会话cookie:保存在浏览器内存中,当会话结束浏览器关闭,会话cookie信息就是丢失;

    持久cookie:保存在浏览器临时文件缓存区中cookie(硬盘上) ,当关闭浏览器结束会话,持久cookie不会被删除

    * 持久cookie存在过期时间,过期后会自动删除

    * 持久cookie 需要设置cookie 有效期 setMaxAge
  • cookie访问有效路径

    携带cookie 必须path一致

    默认 http://localhost/day11/visit 生成cookie ----

    默认path 就是/day11/ (visit资源所在目录就是默认path)

    * 只有在访问 http://localhost/day11/ 目录和子目录情况下 才会携带cookie 信息

    cookie 路径: 设置Cookie 路径  /day11/aa 

    表示在此路径下的所有子目录下的 都可以获取该cookie信息

    所以cc目录下的cc.jsp可以获取cookie信息 而 bb目录下的获取不到cookie 信息

    技术分享
  • 删除持久cookie
    删除持久cookie,可以将cookie最大时效设为0,注意,删除cookie时,path必须一致,否则不会删除

 2.3、cookie案例之——记录上次访问时间案例

  CookieUtils.java——class【参考上面工具类:CookieUtils

  VisitServlet.java——servlet

 1 import java.io.IOException;
 2 import java.util.Date;
 3 
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.Cookie;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 
10 import cn.itcast.day11.utils.CookieUtils;
11 
12 public class VisitServlet extends HttpServlet {
13 
14     public void doGet(HttpServletRequest request, HttpServletResponse response)
15             throws ServletException, IOException {
16         doPost(request, response);
17 
18     }
19 
20     public void doPost(HttpServletRequest request, HttpServletResponse response)
21             throws ServletException, IOException {
22         //   开始coding................
23         response.setContentType("text/html;charset=utf-8");
24         // 1: 先获取 cookie
25         Cookie cookie = CookieUtils
26                 .getCookie("lastvisit", request.getCookies());
27         if (cookie == null) {
28             // 第一次访问
29             response.getWriter().print("你是第一次访问!");
30         } else {
31             // cookie 不为空 已经访问过...
32             String visitTime = cookie.getValue();
33 
34             response.getWriter().print(
35                     "您上次访问的时间:"
36                             +
37                     new Date(Long.parseLong(visitTime)).toLocaleString());
38 
39         }
40         long time = System.currentTimeMillis();//获取当前访问时间
41         cookie = new Cookie("lastvisit", time + "");//设置cookie的值
42         cookie.setMaxAge(3600 * 24 * 3);//设置cookie的有效时间
43         cookie.setPath("/");//设置cookie的有效路径
44         response.addCookie(cookie);//将cookie发送给客户端,保存在浏览器中
45 
46     }
47 
48 }

  *服务端向客户端写出一个新的cookie

  默认cookie都是浏览器内存中进行缓存的 ,当浏览器关闭,会话结束,内存释放

 2.4、cookie应用——显示商品浏览记录

  技术分享

  • 代码实现:Product.jsp
 1 <%@page import="cn.itcast.day11.utils.CookieUtils"%>
 2 <%@ page language="java" contentType="text/html; charset=UTF-8"
 3     pageEncoding="UTF-8"%>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Insert title here</title>
 9 </head>
10 <body>
11 
12   <h2>商品列表</h2>
13   <a href="/day11/look?id=1">mac 电脑</a>
14   <a href="/day11/look?id=2">小米手机3</a>
15   <a href="/day11/look?id=3">雕牌洗衣液2瓶装</a>
16   <a href="/day11/look?id=4">百事可乐一听</a>
17   <hr>
18   <h3>商品浏览记录</h3>
19   <%
20        //   java  code  .....
21         Cookie cookie =   CookieUtils.getCookie("ids", request.getCookies());
22         if(cookie==null){
23             out.print("你尚未浏览商品");
24             return;
25         }
26         String[] pros = {"mac 电脑","小米手机3","雕牌洗衣液2瓶装","百事可乐一听"};
27         String[] ids  = cookie.getValue().split(",");// 1 3 4
28         for(int i=0;i<ids.length;i++){
29               out.print(pros[Integer.parseInt(ids[i])-1]+"<br>");
30         }
31   %>
32 </body>
33 </html>
  • LookProductServlet.java
 1 import java.io.IOException;
 2 
 3 import javax.servlet.ServletException;
 4 import javax.servlet.http.Cookie;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 import cn.itcast.day11.utils.CookieUtils;
10 
11 public class LookProductServlet extends HttpServlet {
12 
13     public void doGet(HttpServletRequest request, HttpServletResponse response)
14             throws ServletException, IOException {
15         doPost(request, response);
16 
17     }
18 
19     public void doPost(HttpServletRequest request, HttpServletResponse response)
20             throws ServletException, IOException {
21         //   开始coding................
22         response.setContentType("text/html;charset=utf-8");
23         /**
24          * servlet 存放用户浏览商品的id 到cookie 1,2 ,3
25          */
26         String id = request.getParameter("id");// 1
27         // 先判断 id
28         Cookie cookie = CookieUtils.getCookie("ids", request.getCookies());
29         if (cookie == null) {
30             // 第一查看
31             cookie = new Cookie("ids", id);
32             cookie.setMaxAge(3600 * 24 * 7);
33             cookie.setPath("/");
34         } else {
35             // 商品浏览 过 判断 id 在不在已知的ids 里面
36             String ids[] = cookie.getValue().split(",");// 1,2,3,4,5
37             if (!check(id, ids)) {
38                 // 不 存在 ...
39                 cookie.setValue(cookie.getValue() + "," + id);
40                 cookie.setMaxAge(3600 * 24 * 7);
41                 cookie.setPath("/");
42             }
43 
44         }
45         response.addCookie(cookie);
46         response.getWriter().print("查看成功<a href=‘/day11/product.jsp‘>返回</a>");
47 
48     }
49 
50     private boolean check(String id, String[] ids) {
51         for (String eachId : ids) {
52             if (eachId.equals(id)) {
53                 return true;
54             }
55         }
56         return false;
57     }
58 
59 }

3、session技术 

  Session :一种将用户信息保存在服务器端技术 ,客户端会持有Session信息对应key,通过key找到session信息

  * Session 占用服务器空间,安全性更高 ,Cookie节省服务器资源,安全性差一些

 

  Session 将用户相关信息保存服务器端,服务器会为每个浏览器创建单独Session对象,每个用户各自数据 保存各自浏览器对应Session对象中。不同用户获取到各自浏览器对应Session 保存数据。

  技术分享

  技术分享

  技术分享

  session依赖cookie机制 实现用户信息的保存.

  通过JSESSIONID  将sessionId()  发送给浏览器 使得浏览器可以保存session id信息

  获取用户的session 绑定数据.

  *注意:  默认级别,发送的cookie 机制是会话级别的  浏览器关闭session对象存在,但是cookie 保存的sessionId 会消失.

 3.1、Session对象创建

  HttpSession 何时创建?  session对象可以在servlet 和jsp 中创建

  •  如果是在jsp  session对象会由容器自动创建
  •  servlet 容器不会自动创建 需要自己手动创建
    HttpSession session =  request,getSession();

  创建好session  容器会自动将seesionId通过cookie 机制  发送给浏览器保存

   * Session 通过cookie 传输 jsessionid 用来在服务器端查找对应Session对象

 3.2、问题:如何实现关掉浏览器后,再开浏览器,上次购买的商品还在?

  如何实现关闭浏览器保留sessionid 信息 ?

  解决方案:修改服务器默认的cookie机制  变成持久化cookie

1 Cookie cookie = new Cookie("JSESSIONID", session.getId());// session对应的cookie信息
2 cookie.setPath("/");
3 cookie.setMaxAge(3600 * 24);//设置sessionId 的有效时间
4 response.addCookie(cookie);//发送给浏览器保存sessionid 信息
5 //浏览器获取的cookie持久化的cookie,下次打开浏览器就可以在服务器端找到sessio对象 (前提是session对象没有被销毁!)

 3.3、Session的生命周期及对象销毁

  • session对象创建

    *servlet 代码request.getSession() 执行时创建(当前会话第一次执行)

    *jsp  容器自动创建session 对象

  • session对象销毁

    1: 自然销毁,默认30分钟过期(连续不使用Session对象时间。即:session 如果一直处于休息状态,容器主动销毁session)

      默认过期时间在tomcat/conf/web.xml 配置:

    1 <session-config>
    2         <session-timeout>30</session-timeout>
    3 </session-config>

      也可手动设置:

    1 setMaxInactiveInterval(int interval)

    2: 程序员主动销毁session 对象

    1 session.invalidate();//session 对象存放的数据就没有了

    3: 非正常关闭服务器(正常关闭服务器Session信息会被序列化到硬盘中 保存tomcat/work目录)

  • 浏览器关闭,session对象是否就销毁了?
    答案:不是,Session保存在服务器端,和浏览器是否关闭没有关系 , 关闭浏览器时删除会话cookie,丢失jsessionid,没有jsession无法找到服务器端对应Session

 3.4、问题:session.removeAttribute 和 session.invalidate区别 ?

  • 1 session.removeAttribute();// 删除当前Session对象中一个属性值
    2 session.invalidate();// 销毁当前Session对象,删除所有属性

4、session 案例——采用一次性验证码(用户登录)

  • 验证码分析图:

  技术分享

  • 代码示例:Register.jsp 
 1 <%@ page language="java" contentType="text/html; charset=utf-8"
 2     pageEncoding="utf-8"%>
 3 <html>
 4 <head>
 5 <meta charset="UTF-8">
 6 <title>Insert title here</title>
 7 <script type="text/javascript">
 8     function change() {
 9         document.getElementById(img).src = /day11/check?
10                 + new Date().getTime();
11     }
12 </script>
13 </head>
14 <body>
15     <h3>注册页面</h3>
16     <h3 style="color:red">${error }</h3>
17     <form action="/day11/register" method="post">
18         用户名<input type="text" name="name"><br>
19                 密码<input type="password" name="password"><br>
20                 验证码<input type="text" name="checkCode"><img src="/day11/check"
21     style="cursor: pointer;" onclick="change();" id="img"><br>
22         <input type="submit" value="注册">
23     </form>
24 </body>
25 </html>            
  • RegisterServlet.java
 1 import java.io.IOException;
 2 
 3 import javax.servlet.ServletException;
 4 import javax.servlet.http.HttpServlet;
 5 import javax.servlet.http.HttpServletRequest;
 6 import javax.servlet.http.HttpServletResponse;
 7 
 8 public class RegisterServlet extends HttpServlet {
 9 
10     public void doGet(HttpServletRequest request, HttpServletResponse response)
11             throws ServletException, IOException {
12         doPost(request, response);
13 
14     }
15 
16     public void doPost(HttpServletRequest request, HttpServletResponse response)
17             throws ServletException, IOException {
18         //   开始coding................
19         // 获取表单提交的信息
20         request.setCharacterEncoding("utf-8");
21         String name = request.getParameter("name");
22         String password = request.getParameter("password");
23         String inputCode = request.getParameter("checkCode");
24 
25         // 第一步 验证验证码信息是否正确
26         // 获取之前session 绑定验证码信息 比对
27         String codeSession = (String) request.getSession()
28                 .getAttribute("check");
29         // 一次验证码 用完就销毁...
30         request.getSession().removeAttribute("check");
31         // 比对 用户输入的code 和 session code 如果一致...
32         if (codeSession.equals(inputCode)) {
33             // 注册事情.....
34             response.sendRedirect("/day11/login.jsp");
35 
36         } else {
37             // 验证码错误 跳回来
38             request.setAttribute("error", "验证码错误");
39             request.getRequestDispatcher("/register.jsp").forward(request,
40                     response);
41         }
42 
43     }
44 
45 }

  * 一次性验证码,当验证码生成后,只使用一次,不管成功或者失败,验证码都将失效

  注意:一次验证码,用完就销毁!

5、session 案例——购物车

  • 购物车逻辑图

  技术分享

  • 代码示例:Product_cart.jsp
 1 <%@page import="cn.itcast.day11.utils.CookieUtils"%>
 2 <%@ page language="java" contentType="text/html; charset=UTF-8"
 3     pageEncoding="UTF-8"%>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Insert title here</title>
 9 </head>
10 <body>
11   <h2>商品列表</h2>
12   mac电脑<a href="/day11/cart?id=1">&nbsp;购买</a><br>
13  小米手机3 <a href="/day11/cart?id=2">购买</a><br>
14   雕牌洗衣液2瓶装<a href="/day11/cart?id=3">购买</a><br>
15  百事可乐一听 <a href="/day11/cart?id=4">购买</a><br>
16   
17   <hr>
18 <a href="/day11/cart.jsp">查看购物车</a>
19 </body>
20 </html>
  • CartServlet.java
 1 import java.io.IOException;
 2 import java.util.HashMap;
 3 import java.util.Map;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 
10 public class CartServlet extends HttpServlet {
11 
12     public void doGet(HttpServletRequest request, HttpServletResponse response)
13             throws ServletException, IOException {
14         doPost(request, response);
15 
16     }
17 
18     public void doPost(HttpServletRequest request, HttpServletResponse response)
19             throws ServletException, IOException {
20         //   开始coding................
21         response.setContentType("text/html;charset=utf-8");
22         String id = request.getParameter("id");// 3 2 3
23         // 通过id --->product
24         String pros[] = { "mac电脑", "小米手机3", "雕牌洗衣液2瓶装", "百事可乐一听" };
25         String pro = pros[Integer.parseInt(id) - 1];
26 
27         // 做一个 购物车
28         Map<String, Integer> cart = (Map<String, Integer>) request.getSession()
29                 .getAttribute("cart");
30         // 2: 判断购物车存在与否?
31         if (cart == null) {
32             // 购物车空
33             cart = new HashMap<String, Integer>();
34             cart.put(pro, 1);
35         } else {
36             // 已经存在购物车
37             if (cart.containsKey(pro)) {
38                 // 表示该购物车已经含有此商品
39                 int count = cart.get(pro);// 得到该购物车商品的数量
40                 // 数量+1
41                 cart.put(pro, count += 1);
42                 // 将已有的商品数量+1
43             } else {
44                 cart.put(pro, 1);
45             }
46 
47         }
48         request.getSession().setAttribute("cart", cart);
49         response.getWriter().print(
50                 "购买成功!<a href=‘/day11/product_cart.jsp‘>返回主页</a>");
51     }
52 
53 }
  • cart.jsp
 1 <%@page import="java.util.*"%>
 2 <%@ page language="java" contentType="text/html; charset=UTF-8"
 3     pageEncoding="UTF-8"%>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Insert title here</title>
 9 </head>
10 <body>
11    <h3>购物车列表</h3>
12    <!--   如何从session  获取购物车信息   -->
13      <%
14         //  1session  获取数据 
15         Map<String,Integer>  cart  = (Map<String,Integer>)session.getAttribute("cart");
16        if(cart!=null){
17                //  2:  如何迭代数据?
18            Set<String>  set =  cart.keySet();
19            Iterator<String> it = set.iterator();
20             while(it.hasNext()){
21                 String  proName = it.next();
22                 int count  = cart.get(proName);
23                 out.print("商品名称:"+proName+"---数量"+count+"<br>");
24             }
25        }else{
26                out.print("购物车无商品");
27        }
28      %>
29 </body>
30 </html>

6、session、request、ServletContext对象的比较

  • ServletContext 每个web工程对应唯一对象,全局的Servlet上下文对象,允许将数据保存      
    ServletContext --- 所有Servlet共享
  • HttpServletRequest 每次请求产生一个HttpServletRequest对象,允许将数据保存request对象中,结合请求转发一起使用
    * 当请求结束后,数据就会删除
  • HttpSession 服务器会为每个客户端创建单独Session对象,允许将数据保存session中 ,session保存的是每个用户各自的数据
    * 用户之间没有影响 (用户购物车、用户登录信息 )
  • 小结
    Servlet三种数据访问范围:ServletContext 、HttpSession、HttpServletRequest 
    1、保存ServletContext数据 ,在服务器关闭时才会删除,生命周期最长,全局都可以访问 (最少使用)
    * 应用场景:网站访问次数、全局数据库连接池 需要保存ServletContext
    2、保存HttpSession数据 ,三种情况下丢失 ,主要保存用户相关数据 
       (不建议存放大规模数据)
    * 应用场景: 用户登录信息、购物信息 保存HttpSession
    
    3、保存HttpServletRequest,当前请求发生时产生,响应结束数据立刻释放 
       (生命周期最短,最建议使用)
    *应用场景: Servlet获得数据处理结果,通过请求转发 传递信息给JSP显示 
    
    三种数据范围提供相同几个方法
    setAttribute
    getAttribute
    removeAttribute 

本章小结

  1、Cookie和Session区别 ?

     Cookie保存会话信息在客户端,Session保存会话信息在服务器端,Session基于Cookie实现的

  2、浏览器关闭后,是不是Session对象就销毁了 ?

     不是,Session保存在服务器端,关闭浏览器丢失jsessionid,

     无法找到服务器对应Session对象了,需要等到Session过期后才会销毁

  3、会话cookie和持久cookie区别 ?

   会话cookie 保存浏览器内存缓存区中,关闭浏览器后,会话cookie就会删除

   持久cookie 保存浏览器临时文件区 硬盘上,存在过期时间,当过期后会自动删除,通过设置maxage为0删除持久cookie

  4、session的三种销毁原因?

   服务器非正常关闭、session过期、invalidate

  5、如何实现关闭浏览器再次打开,Session仍然可以访问?

   将jsessionid 对应cookie 持久化

cookie和session

标签:

原文地址:http://www.cnblogs.com/cb0327/p/5247619.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!