返回顶部

Cookie和Session

会话概述

什么是会话:用户打开一个浏览器访问页面,访问网站的很多页面,访问完成后将浏览器关闭的过程称为是一次会话。
常见的会话技术:
* Cookie:将数据保存到客户端浏览器。
* Session:将数据保存到服务器端。

Cookie 技术的使用

向浏览器保存数据:
HttpServletResponse 的方法:
  * void addCookie(Cookie cookie);
获得浏览器带过来的 Cookie:
HttpServletRequest 的方法:
  * Cookie[] getCookies();
创建一个 Cookie 对象:
  * Cookie(String name,String value);

Cookie 的常用 API

* getName();
* getValue();
* setDomain(String domain); -- 设置 Cookie 的有效域名. // www.baidu.com music.baidu.com
* setPath(String path); -- 设置 Cookie 的有效路径.
* setMaxAge(int maxAge); -- 设置 Cookie 的有效时间.(设置为0,即删除cookie)

Cookie 的分类有关:
* 会话级别的 Cookie:默认的 Cookie.关闭浏览器 Cookie 就会销毁.
* 持久级别的 Cookie:可以设置 Cookie 的有效时间.那么关闭浏览器 Cookie 还会存在. 手动销毁持久性 Cookie. setMaxAge(0)---前提是有效路径必须一致.

// 记录用户的上次登录访问时间
public class CountServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        Integer count = (Integer) this.getServletContext().getAttribute("count");
//      response.getWriter().println("<h1>现在网站被访问的次数为:"+count+"</h1>");
        
        /**
         * 获得浏览器中带过来的所有的Cookie信息,从数组中查找有没有指定名称的Cookie
         * 判断用户是否是第一次访问:(从数组中没有找到指定名称的Cookie)
         * * 如果是第一次:显示欢迎,记录当前访问的时间存入到Cookie中.
         * * 如果不是第一次:显示欢迎,上一次访问时间,同时记录当前访问的时间存入到Cookie中。
         */
        // 获得浏览器带过来的所有的Cookie:
        Cookie[] cookies = request.getCookies();
        // 从数组中查找指定名称的Cookie:
        Cookie cookie = CookieUtils.findCookie(cookies, "lastVisit");
        // 判断是否是第一次:
        if(cookie == null){
            // 第一次访问
            response.getWriter().println("您是第"+count+"位访客!");
        }else{
            // 不是第一次
            Long l = Long.parseLong(cookie.getValue());
            Date d = new Date(l);
            response.getWriter().println("您是第"+count+"位访客! 上次访问时间是:"+d.toLocaleString());
        }
        // 创建一个Cookie对象:
        Cookie c = new Cookie("lastVisit",""+System.currentTimeMillis());
        // 保存到浏览器端:
        response.addCookie(c);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
记录用户的上次登录访问时间
// 记录用户的商品浏览记录
public class ProductServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /**
         * * 接收商品id.
         * * 接收从客户端带过来的所有Cookie.
         * * 从Cookie的数组中查找指定名称的Cookie.
         * * 判断是否是第一次浏览商品:
         *     * 第一次浏览商品
         *        * 直接将商品的ID存入到Cookie.
         *        * 将Cookie回写到浏览器.
         *     * 不是第一次浏览商品 1-2
         *        * 判断当前的商品是否已经在浏览记录.
         *            * 已经存在: 2-1 移除当前元素,将当前元素添加到最开始.
         *            * 没在浏览记录中: 
         *                * 判断是否已经超过了最大长度:如果超过 2-1-3:删除最后一个 将当前元素添加到最前面.
         *                * 没有超过:直接将该元素添加到最前位置.
         *        * 将转换的id的值存入到Cookie,回写浏览器.
         */
        // 接收id:
        String id = request.getParameter("id");
        // 获得所有的Cookie的信息:
        Cookie[] cookies = request.getCookies();
        // 判断是否是第一次:
        Cookie cookie = CookieUtils.findCookie(cookies, "history");
        if(cookie == null){
            // 第一次浏览商品
            Cookie c = new Cookie("history",id);
            c.setPath("/day11");
            c.setMaxAge(60*60*24*7);
            response.addCookie(c);
        }else{
            // 不是第一次浏览
            // 判断选择的商品是否已经在浏览记录中 2-1
            String value = cookie.getValue();
            String[] ids = value.split("-");
            // 将数组变为集合:
            LinkedList<String> list = new LinkedList<String>(Arrays.asList(ids));
            if(list.contains(id)){
                // 之前浏览过该商品
                list.remove(id); // 1-2-3
                list.addFirst(id);
            }else{
                // 没有浏览过该商品.
                if(list.size() >=3 ){
                    // 超过3个
                    list.removeLast();
                    list.addFirst(id);
                }else{
                    // 没到3个.
                    list.addFirst(id);
                }
            }
            // 将list中的元素取出,使用-连接上保存到Cookie,写回浏览器.
            StringBuffer sb = new StringBuffer();
            for(String s:list){
                sb.append(s).append("-");
            }
            String sValue = sb.toString().substring(0,sb.length()-1);
            System.out.println(sValue);
            // 存入到Cookie中
            Cookie c = new Cookie("history",sValue);
            c.setPath("/day11");
            c.setMaxAge(60*60*24*7);
            response.addCookie(c);
        }
        request.getRequestDispatcher("/demo2/product_info.htm").forward(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
记录用户的商品浏览记录
// 删除持久性的Cookie
public class ClearServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie cookie = new Cookie("history",null);
        cookie.setPath("/day11");
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        response.sendRedirect("/day11/demo2/product_list.jsp");
    }

    /**
     * @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);
    }
}
删除持久性的Cookie

 

Session 概述

Cookie 本身是有大小和个数的限制.Session 没有限制.Cookie 的数据保存在客户端, Session 数据保存在服务器端.
Session 的执行原理:基于 Cookie 的.

使用 Session

* 获得 Session:request.getSession();
* 设置和获取 Session 参数:
  request.getSession().getAttribute("cart");
  request.getSession().setAttribute("cart", map);

重复提交的问题

添加完商品之后,转发到一个页面,刷新该页面.
网速很慢,点击提交的按钮,其实已经在提交了但是网速慢,不停的点击提交.
解决重复提交的根本解决办法:令牌机制(一次性).
  生成随机的令牌保存在session中.
  在表单的提交的时候,将随机的令牌放入到表单的隐藏字段中.
  在Servlet中获得session中和表单中的令牌是否一致.
  如果一致执行插入操作,不一致跳转到其他页面.将令牌销毁.

    // 判断是否是重复提交:
    String token1 = (String)request.getSession().getAttribute("token");
    String token2 = request.getParameter("token");
    // 清空session中的令牌:
    request.getSession().removeAttribute("token");
    if(!token2.equals(token1)){
        request.setAttribute("msg", "亲!您已经提交过!请不要重复提交了!");
        request.getRequestDispatcher("/jsp/msg.jsp").forward(request, response);
        return;
    }
判断是否是重复提交

session 的创建和销毁及作用范围

* 创建:服务器端第一次调用 getSession() 创建 session.
* 销毁:三种情况销毁 session:
* 1.session 过期. 默认过期时间为 30 分钟.
* 2.非正常关闭服务器.如果正常关闭 session 序列化到硬盘.
* 3.手动调用 session.invalidate();
* 作用范围:多次请求.(一次会话)

Session 失效时间设置

1. 在 web 容器中设置(此处以 tomcat 为例)
在 tomcat-5.0.28\conf\web.xml 中设置,以下是 tomcat 5.0 中的默认配置:

<session-config>
<session-timeout>30</session-timeout>
</session-config> 

Tomcat 默认 session 超时时间为30分钟,可以根据需要修改,负数或0为不限制 session 失效时间。

2. 在工程的 web.xml 中设置

<!-- 时间单位为分钟 -->
<session-config>
<session-timeout>15</session-timeout>
</session-config>

3. 通过 Java 代码设置

session.setMaxInactiveInterval(30*60);//以秒为单位

三种方式优先级:1 < 2 <3

// 商品添加到购物车
public class CartServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 接收商品名称:
        String name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");
        // 创建Map集合用于保存购物信息.Map<String,Integer> Map的key是商品的名称 value是购买的数量.
        Map<String,Integer> map = (Map<String, Integer>) request.getSession().getAttribute("cart");
        if(map == null){
            map = new LinkedHashMap<String,Integer>();
        }
        // 判断购物车中是否已经买了该商品.
        if(map.containsKey(name)){
            // map中已经有该商品:// * 如果购物车中已经有该商品: 获得到Map中该商品的数量+1。 存回到Map集合中.
            Integer count = map.get(name);
            count++;
            map.put(name, count);
        }else{
            // map中没有该商品.// * 如果购物车中没有改商品: 将商品添加到Map集合中 数量1.
            map.put(name, 1);
        }
        
        // * 将Map集合保存到session中.
        //移除一个(一个键值对)session  request.getSesion().removeAttribute ();
        request.getSession().setAttribute("cart", map);
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().println("<h3><a href='/day11/demo2/product_list.jsp'>继续购物</a> | <a href='/day11/demo2/cart.jsp'>去结算</a></h3>");
    }
}
商品添加到购物车
// 验证码校验
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 校验验证码程序:
        String code1 = request.getParameter("code");
        String code2 = (String) request.getSession().getAttribute("code");
        request.getSession().removeAttribute("code");
        if(!code1.equalsIgnoreCase(code2)){
            request.setAttribute("msg", "验证码输入错误!");
            request.getRequestDispatcher("/demo2/login.jsp").forward(request, response);
            return ;
        }
   ...
}

// 使用JS控制图片切换:
 <script type="text/javascript">
    function changeImg(){
        document.getElementById("img1").src="/day11/CheckImgServlet?time="+new Date().getTime();
    }
 </script>
验证码校验

 

posted @ 2017-10-09 01:33  jaden好青年  阅读(158)  评论(0编辑  收藏  举报