Cookie和Session

一 Cookie

01 基础理论

1、会话技术

什么是会话呢?

从浏览器第一次访问服务器(Tomcat) 开始一直到 浏览器关闭为止,这一整套的流程。称之为一次会话。

效果图

Cookie和Session_第1张图片

2、技术分类

会话技术是什么?有哪些呢?

会话技术:
    就是在 一次会话当中,需要使用到的技术点,主要可以完成数据的存储和数据的共享。
​
会话技术的分类:
    (1) 客户端的会话技术: cookie  存储到浏览器当中
    (2) 服务端的会话技术: session 存储到服务器会话域当中

02 快速入门

1、案例代码

Cookie 的快速入门

操作步骤

1. 创建 Cookie 的对象,创建对象的过程当中,可以进行值的存放。
    Cookie c = new Cookie(String类型的键, String类型的值);
​
2. 发送 Cookie 给浏览器
    response.addCookie(c);
​
3. 下次获取 Cookie 的数据值
    Cookie[] cookieArray = request.getCookies();

案例代码

/***
 * Cookie的快速入门
 *
 * http://localhost:8080/JavaWebDay17/CookieDoor01Servlet
 */
@WebServlet("/CookieDoor01Servlet")
public class CookieDoor01Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("CookieDoor01Servlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("CookieDoor01Servlet.doPost");
        //【1】创建 Cookie 的对象
        Cookie c = new Cookie("message","helloCookie");
        //【2】发送Cookie到浏览器当中
        resp.addCookie(c);
    }
}
/***
 * Cookie的快速入门
 *
 * http://localhost:8080/JavaWebDay17/CookieDoor02Servlet
 */
@WebServlet("/CookieDoor02Servlet")
public class CookieDoor02Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("CookieDoor02Servlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("CookieDoor02Servlet.doPost");
        //【3】获取到客户端的 cookie 信息
        Cookie[] cookeArray = req.getCookies();
        //遍历数组
        for (Cookie c : cookeArray) {
            String name = c.getName();
            if (name!=null && name.equals("message")){
                //获取到值
                String value = c.getValue();
                System.out.println(name+","+value);
            }
        }
    }
}

2、执行过程

Cookie和Session_第2张图片

校验执行过程:

第一次访问

Cookie和Session_第3张图片

 第二次访问 Cookie和Session_第4张图片

03 相关细节

1、提出问题

1. 我们 可不可以发送多个 Cookie 数据呢?
2. Cookie 可以在浏览器当中保存多长时间呢?
3. Cookie 能不能存储中文或者特殊字符?
4. Cookie 能不能进行不同情况下共享使用?

2、解决问题

问题1:我们 可不可以发送多个 Cookie 数据呢?

回答:

可以发送多个 Cookie 数据。 
那么怎么发送呢?
创建多次的 Cookie 对象,发送多次就可以了。
Cookie c1 = new Cookie("name","zhangsan");
Cookie c2 = new Cookie("age","23");
response.addCookie(c1);
response.addCookie(c2);

问题2:Cookie 可以在浏览器当中保存多长时间呢?

回答:

默认情况下,我们的 Cookie 随着浏览器的关闭,会话结束了,Cookie 也会消失,这种我们叫做 "临时Cookie"
​
如何设置 Cookie 的有效期呢?
    可以去采用 setMaxAge(int) 定义Cookie 的有效期。
    参数信息 int 取值不同,有效期也不相同。
        1. 如果参数是 正数, 则表示 有效期是多少秒。 (单位是秒) c.setMaxAge(30) 表示可以存活30秒
        2. 如果参数是 负数, 则表示 默认情况, 关闭浏览器, cookie 直接消失
        3. 如果参数是 零, 则表示 清除Cookie数据

问题3:Cookie 能不能存储中文或者特殊字符?

回答:

中文: 在Tomcat8之前是 不可以存储到 Cookie 当中的, 在Tomcat8之后是 可以存储到 Cookie 当中。
特殊字符: 在 Cookie 里面是不可以存储的
​
问题:
    如果我们一定要存储 中文或者特殊字符,应该怎么办呢?
    解决方案,采用 编码转换。转换编码存储,拿到数据之后,解码。
    URL编码:  URLEncoder.encode("需要编码的字符串","编码方式UTF-8");
    URL解码:  URLDecoder.decode("需要解码的字符串","编码方式UTF-8");

问题4:Cookie 能不能进行不同情况下共享使用?

回答:

1. 共享一:
    我们发布的 第一个 JavaWeb 模块的代码在 Tomcat 服务器上面,
    我们再次发布 另一个 JavaWeb 模块代码在 Tomcat 服务器上面,
    两者的 Cookie 可以实现共享吗?
    默认情况下是不可以实现共享的。
    问题是:如果想要实现共享应该怎么办呢?
    需要采用方法提升 Cookie 的作用范围。   setPath("/")  这里的斜杠指的是虚拟路径
​
2. 共享二:
    我们发布的 JavaWeb 项目代码 在 不同的 Tomcat 服务器上面,可不可以实现共享呢?
    默认情况下是不可以实现共享的。
    问题是: 如果两个 tomcat 服务器上面的 Cookie 想要实现共享,怎么办?
    举例:
        xueshu.baidu.com  学术
        news.baidu.com    新闻
        tieba.baidu.com   贴吧
    其中 .baidu.com 称之为 一级域名。  xueshu、news、tieba 称之为 二级域名。
    如果我们给 cookie 的范围设置为 一级域名的级别,则二级域名的内容,可以实现 Cookie 共享
    存在方法:  setDomain(".baidu.com");   设置之后,二级域名就可以访问共享 Cookie了

04 特点作用

1、Cookie特点

1. Cookie 是存在于 客户端浏览器当中的。
2. 在浏览器当中,对于单个 Cookie 而言,有大小限制,最大为 4KB (说明:不同浏览器限制不相同)
3. 在浏览器当中,对于同一个域名下面的 Cookie 而言,有数量的限制,最多20个(说明:不同浏览器数目限制不同)

2、Cookie作用

1. 存储少量非敏感的数据。
2. 在不登录的情况下,可以实现浏览器对客户的识别。
    例如: 偏好设置。
    在百度当中,搜索引擎的做偏好设置。

效果图

Cookie和Session_第5张图片

备注:如果采用登录,永久性保存,则将偏好设置保存到 服务器的数据库上面。

如果没有登录,临时存储,会保存到 Cookie 当中

05 基础案例

1、需求说明

说明

在我们访问一个 Servlet 的时候,如果是第一次访问,则显示 "您好,首次访问"
如果不是第一次访问,则显示 "欢迎回来,您的上次访问时间是 2088年9月2日15:19:48"

分析

Cookie和Session_第6张图片

2、案例代码

/***
 * 案例: 最后一次的访问时间。
 *
 * 地址: http://localhost:8080/JavaWebDay17/LastServlet
 */
@WebServlet("/LastServlet")
public class LastServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 直接查找 cookie 是否存在
        Cookie c = findCookieByName("lasttime", req);
        //2. 分情况考虑问题了
        String message;
        if (c == null){
            message = "您好,首次访问";
        }else{
            String value = c.getValue();
            message = "欢迎你" + URLDecoder.decode(value,"UTF-8");
        }
        //3. 展示数据
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println(message);
        //4. 需要将数据保存到 cookie 当中
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String timeStr = sdf.format(new Date());
        timeStr = URLEncoder.encode(timeStr,"UTF-8");
        Cookie timeCookie = new Cookie("lasttime",timeStr);
        //添加一个过时时间,有效期 30天
        timeCookie.setMaxAge(60*60*24*30);
        resp.addCookie(timeCookie);
    }


    //定义一个方法,专门用于查找是否存在指定name的 cookie数据
    protected Cookie findCookieByName(String name, HttpServletRequest req) throws ServletException, IOException {
        //获取到所有的 Cookie 信息
        Cookie[] cookies = req.getCookies();
        //定义Cookie 是否找到
        Cookie c = null;
        //判断当前的 cookies 没有数据直接返回, 或者 传入的名称直接是 null
        if (cookies == null || name == null){
            return c;
        }
        //表示 cookies 数组当中存在数据
        for (Cookie child : cookies) {
            //判断 name 是否在 数组的元素 name 当中,如果在,则赋值
            if (name.equals(child.getName())){
                c = child;
                break;
            }
        }
        return c;
    }
}

二 Session

01 基础理论

1、回顾四大域对象

1. 应用域 ServletContext
2. 会话域 Session
3. 请求域 Request
4. 页面域 PageContext

四个域对象,都存在三个方法

1. 存值   void setAttribute(String,Object)
2. 取值   Object getAttribute(String)
3. 删除值  void removeAttribute(String) 

2、快速入门

/***
 * Session 会话域的快速入门
 *
 * 网址: http://localhost:8080/JavaWebDay17/SessionDoor1Servlet
 */
@WebServlet("/SessionDoor1Servlet")
public class SessionDoor1Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SessionDoor1Servlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SessionDoor1Servlet.doPost");
        //获取到会话域对象 session
        HttpSession session = req.getSession();
        //存值的操作
        session.setAttribute("name","zhangsan");
        //-----------
        //如果采用的是请求域
        req.setAttribute("pass","666666");
    }
}
/***
 * Session 会话域的快速入门
 *
 * 网址: http://localhost:8080/JavaWebDay17/SessionDoor2Servlet
 */
@WebServlet("/SessionDoor2Servlet")
public class SessionDoor2Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SessionDoor2Servlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SessionDoor2Servlet.doPost");
        //获取到会话域对象 session
        HttpSession session = req.getSession();
        //获取值
        Object name = session.getAttribute("name");
        System.out.println("name = " + name);
        //--------------
        //如果采用的是请求域
        Object pass = req.getAttribute("pass");
        System.out.println("pass = " + pass);
    }
}

02 实现原理

1、抓包工具效果

Cookie和Session_第7张图片

2、原理图效果

Cookie和Session_第8张图片

 小结: session 的实现是 基于 Cookie 的

03 相关细节

1、提出问题

1. 当客户端浏览器关闭之后,服务器不关闭,再次启动客户端浏览器,获取到Session 是不是同一个?
2. 客户端不关闭,服务器关闭,再次启动服务器,获取到 Session 是不是同一个?
3. Session 失效的时间是什么?

2、解决问题

问题1:当客户端浏览器关闭之后,服务器不关闭,再次启动客户端浏览器,获取到Session 是不是同一个?

回答:

不是同一个。
​
验证方式:
    直接打印输出 session 对象,展示地址值,就可以看到效果。
​
问题:
    不是同一个,但是会存在影响,两次的 session 对象不同,如果需求是 必须相同,应该怎么办呢?
解决:
    cookie 存在有效期,当浏览器关闭之后,会持续的保存着。有一段有效期。
    方法是 cookie.setMaxAge(60*60*24)  设置为1天的时间

案例代码

/***
 * 路径:  http://localhost:8080/JavaWebDay17/SessionDemo01Servlet
 */
@WebServlet("/SessionDemo01Servlet")
public class SessionDemo01Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SessionDemo01Servlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("SessionDemo01Servlet.doPost");
        //直接获取到 Session 的对象
        HttpSession session = req.getSession();
        //---------------------------
        //定义一个 Cookie 用于保存 Session 的id信息
        Cookie c = new Cookie("JSESSIONID",session.getId());
        //设置有效期, 设置为1小时
        c.setMaxAge(60*60);
        //发送 cookie 到客户端浏览器里面保存
        resp.addCookie(c);
        //---------------------------
        //直接打印输出 session 展示地址值
        System.out.println("session = " + session);
    }
}

你可能感兴趣的:(Java基础,tomcat,cookie,session)