Cookie和Session

摘要:
常见会话技术:*Cookie:将数据保存到客户端浏览器*会话:将数据保存至服务器*///获取浏览器带来的所有Cookie:Cookie[]cookies=请求。getCookies()//从数组中查找具有指定名称的cookie:Cookiecookie=CookieUtils。findCookie//判断是否是第一次:如果{//第一次访问response.getWriter().println(“您是”+count+“访问者!”);}否则{//这不是Long=Longl.parseLong;Dated=newDate;response.getWriter().println(“您是”+count+“访问者!

会话概述

什么是会话:用户打开一个浏览器访问页面,访问网站的很多页面,访问完成后将浏览器关闭的过程称为是一次会话。
常见的会话技术:
* 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)---前提是有效路径必须一致.

Cookie和Session第1张Cookie和Session第2张
// 记录用户的上次登录访问时间
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);
    }
}
记录用户的上次登录访问时间
Cookie和Session第3张Cookie和Session第4张
// 记录用户的商品浏览记录
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和Session第5张Cookie和Session第6张
// 删除持久性的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中和表单中的令牌是否一致.
  如果一致执行插入操作,不一致跳转到其他页面.将令牌销毁.

Cookie和Session第7张Cookie和Session第8张
    // 判断是否是重复提交:
    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

Cookie和Session第9张Cookie和Session第10张
// 商品添加到购物车
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='http://t.zoukankan.com/day11/demo2/product_list.jsp'>继续购物</a> | <a href='http://t.zoukankan.com/day11/demo2/cart.jsp'>去结算</a></h3>");
    }
}
商品添加到购物车
Cookie和Session第11张Cookie和Session第12张
// 验证码校验
    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="http://t.zoukankan.com/day11/CheckImgServlet?time="+new Date().getTime();
    }
 </script>
验证码校验

免责声明:文章转载自《Cookie和Session》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux网络编程——进程池实现过程详解(2)FSA/FSM/FST下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

《图解 HTTP》 摘要一

学习过程对书本的内容的摘要以及总结,逐步完善,带有个人理解成分。 Web 及网络基础 使用 HTTP 协议访问 Web 客户端:通过获取请求获取服务资源的 Web 浏览器等 HTTP 全称:HtyperText Transfer Protocol WWW 全称:Wrold Wide Web SGML 标准通用标记语言 全称:Standard Gener...

[Android测试] Appium的一些坑问题错误解决 与 技巧集锦

转:https://blog.csdn.net/niubitianping/article/details/52624417 1. error: Failed to start an Appium session, err was: Error: Requested a new session but one was in progress 之前的会话没有...

爬虫cookies详解

cookies简介 cookie是什么? Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于 RFC2109 和 2965 中的都已废弃,最新取代的规范是 RFC6265[1]。Cookie其实就是浏览器缓存。 cookie的生命周期 会话cooki...

CAS实现SSO单点登录原理

一、不落俗套的开始 1、背景介绍 单点登录:Single Sign On,简称SSO,SSO使得在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 CAS框架:CAS(Central Authentication Service)是实现SSO单点登录的框架。 2、盗一张学习CAS绝大多都看过的图以及执行部分分析 注:已分不清原创,此...

会话、服务器ASP.NET中Session的用法by小雨

在写这篇文章之前,xxx已经写过了几篇关于改会话、服务器-主题的文章,想要了解的朋友可以去翻一下之前的文章 我们可以应用 Session 象对存储特定的用户会话所需的息信。当用户在应用程序的页之间跳转时,存储在 Session 象对中的量变不会除清,而用户在应用程序中拜访页面时,这些量变终始存在。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话...

2020前端面试题常问集锦

以下为常备面试题集锦,面好多家公司大都问的如此(后续更新补);还有一些算法和手写代码后面整理; js陈述类型1、Es6的class和构造函数的区别: class xx { }(1)不存在变量提升(2)方法默认是不可枚举的,class所有方法没有原型对象prototype也没有构造器不能用new来调用; 2、普通函数和箭头函数的区别?(1)this指向不...