Cookies, Session

由于HTTP协议是无持续状态的协议,所以在 HTTP协议 实现会话状态保持是一个挑战,目前主要的做法是采用 Cookies 和 Session 技术解决。

HTTP协议是无持续状态的 数据发送完毕,连接立即释放。 这种工作方式可以使用服务器的资源充分复用,可以为更多客户端服务。简称:无状态协议

无状态协议:由于服务器服务结束以后,释放了连接,不再与客户端保持状态, 无法记住客户端, 如: 客户是否登录过。

Cookies 技术

Cookies 技术,是在HTTP协议基础之上实现状态保持技术,其工作原理与会员卡类似:

  1. 在客户端第一次来访时候,发会员卡(cookie)。

  2. 服务端可以将信息记录到卡上。

  3. 客户端在每次来访时候, 都要带上会员卡用于识别身份。

  4. 状态信息记录在 会员卡 上。

Cookies 原理:

  1. 在浏览器第一次来访时候,发Cookies。

  2. 服务器可以将信息记录到Cookies上。

  3. 浏览器在每次来访时候, 都要带上Cookies用于识别身份。

  4. 状态信息记录在 Cookies 上。

Cookie 饼干,当年 Netscape 公司设计了一个无厘头名字。

Cookies的使用:

  1. Cookies 现在作为HTTP协议扩展功能,被浏览器广泛支持。

  2. Cookies 利用 HTTP 协议 消息头传送数据。

  3. Cookies 是一个HTTP协议扩展标准,其协议头是严格规定的。

  4. Java Servlet API 提供Cookies API,只需要使用这些API就能自动下发Cookies,自动获取上传Cookies。

Cookie中的特殊字符和中文:

由于Cookie是在Http协议头部传送的, Http协议头必须是 ISO8859-1 编码,并且不能使用特殊字符和中文。

  1. 利用 Escape 编码进行解决,是HTTP协议标准。

  2. 数据加入Cookie之前进行编码即可。

  3. Java 提供了编码API

    URLEncoder.encode("您好Cookie", "UTF-8")

利用Java Servlet API 下发Cookie

下发Cookie,response 对象上有下发Cookies API:

public class AddCookieServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    /**
     *  请求路径 /add-cookie
     */
    protected void doGet(
            HttpServletRequest request, 
            HttpServletResponse response) 
        throws ServletException, IOException {
        // 利用response下发一个Cookie到浏览器
        
        //1. 创建一个Cookie
        Cookie cookie = new Cookie("message", 
            URLEncoder.encode("Hello World!","UTF-8"));
        Cookie cookie2 = new Cookie("test", 
            URLEncoder.encode("您好Cookie", "UTF-8"));
        
        //2. 下发Cookie
        response.addCookie(cookie);
        response.addCookie(cookie2);
        
        response.setContentType("text/html; charset=UTF-8");
        response.getWriter().print("OK"); 
    }
​
}

读取request带回的Cookie

request中提供了读取浏览器带回的Cookie数据方法,必要时候需要解码处理

public class GetCookieServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
​
    /**
     * 请求路径 /get-cookie
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 读取请求中带回Cookie
        Cookie[] cookies = request.getCookies();
        // 如果没接收到任何Cookie,getCookies()返回null
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                System.out.print(cookie.getName() + ":");
                System.out.println(
                    URLDecoder.decode(cookie.getValue(), "UTF-8"));
            }
        }
​
        response.setContentType("text/html; charset=UTF-8");
        response.getWriter().println("OK");
    }
​
}

Cookie的属性

Cookie的生命时间

  1. 默认情况下, Cookie保存在浏览器内存中,浏览器关闭就会消失,适合保存与当前 浏览器会话 有关的数据。

  2. 下发时候设置Cookie的存活时间,设置以后Cookie会保存在浏览器的硬盘上, 会长期保存, 再次打开浏览器,Cookie还在! 适合保存长期有效的数据。 比如登录用户名。

如: 记住用户名功能!可以使用Cookie实现

  1. 如果想删除Cookie,则设置存活时间为0

不要使用Cookie保存密码!!!!

案例:

public class CookieAgeServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    /**
     * 请求路径 /cookie-age
     */
    protected void doGet(
            HttpServletRequest request,
            HttpServletResponse response) 
        throws ServletException, IOException {
        //下发两个 Cookie 一个是默认是Cookie,一个是
        //一天有效的,不关闭浏览器查看回送情况
        //再次打开浏览器检查回送情况
        
        Cookie c1 = new Cookie("c1", "sort");
        Cookie c2 = new Cookie("c2", "oneDay");
        c2.setMaxAge(60*60*24); 
        
        //下发Cookie
        response.addCookie(c1);
        response.addCookie(c2);
        
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().print("OK"); 
    }
​
}

Cookie的域名和路径

  1. 浏览器在保存Cookie时,每个网站保存一组对应Cookie,在发送时候发送到对应的网站。 根据域名区分不同的网站

  2. 同一个网站的Cookie按照路径分级存储,回传时候按照路径级别回传:

    1. 目录中可以收到当前目录的Cookie和上级目录的Cookie

    2. 外面发里面能拿 但是里面发外面拿不了

  3. 下发Cookie时候,默认情况下按照当前目录层次保存Cookie,可以利用setPath属性设置Cookie的保存路径。

案例:

public class SubCookieDemo extends HttpServlet {
    private static final long serialVersionUID = 1L;
    /**
     * 请求路径: /sub/cookie
     */
    protected void doGet(
            HttpServletRequest request,
            HttpServletResponse response) 
                    throws ServletException, IOException {
        //下发子目录 /sub 的Cookie
        Cookie c3 = new Cookie("c3", "sub");
        response.addCookie(c3);
        
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().print("OK"); 
    }
}

//作业: 用cookie来实现记住用户名密码

Session 原理

Cookie的问题

  1. 不安全,可以被冒用,涂改

  2. 不能存储大量信息,一般不超过4K

  3. 只能存储文本

  4. Cookie保存在客户端不安全,不能存储敏感信息,如: 密码·

Session 在Cookie基础之上解决了安全问题。

Session解决问题的方案类似于 银行卡!

  1. Session将数据存储在 服务器 端

  2. Session利用Cookie存储了一个 号码,用于识别用户身份,称为SessionID

  3. 服务端设置了一个集合,这个集合就是Session,并且与SessionID绑定

  4. 第一次创建Session时候,服务器创建Session集合对象并且分配Session的ID,将Session ID自动下发到 浏览器Cookie。

  5. 第二次请求时候浏览器通过Cookie传送回 SessionID,服务器会找到对应Session集合。 为用户提供存储服务。

  6. 当客户端SessionID丢失时或者浏览器离线以后,服务器会定时销毁Session。 默认是30分钟.

Java 提供了Session API

HttpSession session = request.getSession();-为什么是获取session,服务端设置了一个集合,这个集合就是Session,
session.setAttribute("msg", "Hello World!");

案例将数据存储到Session中:

public class SetSessionServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    /**
     * 请求路径 /set-session
     */
    protected void doGet(
            HttpServletRequest request, 
            HttpServletResponse response) 
        throws ServletException, IOException {
        
        HttpSession session = request.getSession();
        session.setAttribute("msg", "Hello World"); 
        
        response.setContentType("text/html");
        response.getWriter().print("OK"); 
        
    }
​
}

从session读取数据:

public class GetSessionServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
​
    /**
     * 请求路径 /get-session
     */
    protected void doGet(
            HttpServletRequest request, 
            HttpServletResponse response) 
        throws ServletException, IOException {
        HttpSession session = request.getSession();
        String msg = (String)session.getAttribute("msg");
        System.out.println(msg);
        
        response.setContentType("text/html");
        response.getWriter().println("OOK");
    }
​
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值