zoukankan      html  css  js  c++  java
  • 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.28confweb.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>
    验证码校验
  • 相关阅读:
    Creating Bootstrapper Packages
    匹配Google查询URL关键字
    DotNetNuke模块Unhandled error loading module问题解决
    当WCF的定义过大时vs.net无法添加引用.
    SQL 去除时间
    2012年终总结(一)
    GDI+生成证书带二维码
    linq to xml基础
    Jquery ligerUI的使用
    vs2012 用户类和xml 、xaml不高亮显示的解决办法
  • 原文地址:https://www.cnblogs.com/boomoom/p/10134899.html
Copyright © 2011-2022 走看看