• Servlet/JSP-05 Cookie


    一. 问题?

      HTTP协议是一种无状态协议,服务器本身无法识别出哪些请求是同一个浏览器发出的,浏览器的每一次请求都是独立的。现实业务中服务器有时候需要识别来自同一个浏览器的一系列请求,例如购物车,登录状态记录;所以 WEB 服务器必须能够采用一种机制来唯一的标识一个用户,并且记录该用户的状态。

    二. 会话和会话状态

    1.WEB 应用中的会话是指一个客户端浏览器与 WEB 服务器之间连续发生的一系列请求和响应过程

    2.WEB 应用的会话状态是指 WEB 服务器与浏览器在会话过程中产生的状态信息,借助会话状态,WEB 服务器能够把属于同一个会话的一系列请求和响应过程关联起来

    在 Servlet 规范中,常用以下两种机制完成会话跟踪:cookie 和 session

    三. cookie机制

    1. cookie 机制采用的是在客户端保持 HTTP 状态信息的方案。cookie 是在浏览器访问 WEB 服务器的某个资源时,由 WEB 服务器在 HTTP 响应消息头中附带传送给浏览器的一个小文本文件。一旦浏览器保存了某个 cookie,那么它在以后每次访问服务器时,都会在 HTTP 请求头中将这个 cookie 回传给服务器,供服务器识别本次会话状态。

    2.底层实现原理

      WEB 服务器通过在 HTTP 响应消息中增加 Set-Cookie 响应头字段将 cookie 信息发送给浏览器;浏览器则通过在 HTTP 请求头中增加 Cookie 字段回传给 WEB 服务器。

    3.cookie的特性

      a. 一个 cookie 只能标识一种信息,至少包含一个标识信息的名称(name)和设置值(value)

      b. 一个服务器可以给一个浏览器发送多个 cookie, 一个浏览器可以存储多个服务器提供的 cookie。

      c. 浏览器一般允许存放300个 cookie, 每个站点最多存放20个 cookie,每个 cookie 的大小限制为4KB

    4. cookie相关的类和方法

      ① Servlet中提供了一个 javax.servlet.http.Cookie类来封装 cookie 信息,它包含有生成 cookie 信息和提取 cookie 信息各个属性的方法。

        Cookie类的方法:

          public Cookie(String name, String value)  构造方法

          getName()

          setValue(String value) 和 getValue()

          setMaxAge 和 getMaxAge(int ms)

          setPath 和 getPath

      ② HttpServletResponse接口中定义了一个 addCookie 方法,它用于在发送给浏览器的 HTTP 响应信息中增加一个 Set-Cookie 的响应头字段

      ③ HttpServletRequest 接口中定义了一个 getCookies 方法, 它用于从 HTTP 请求信息的 cookie 请求头字段中读取所有的 cookie 信息。

    5. 代码示例

      ① cookie 的发送

        发送 cookie 需要使用 HttpServletResponse接口的 addCookie 方法,将 cookie 插入到Set-Cookie 的 HTTP响应头中。由于这个方法并不修改之前的任何 cookie, 而是创建新的 cookie,因此此方法是 addCookie。

      ② cookie 的读取

        使用 HttpServletRequest 接口的 getCookies 方法获取一个 Cookie 数组,然后对数组进行遍历,调用 Cookie 的 getName() 和 getValue() 方法

      浏览器第一次请求,无cookie,第二请求显示cookie

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ page session="false" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
        <%
            // 在Servlet规范中使用Cookie类代表cookie
    
            //3.从request中获取Cookie
            Cookie[] cookies = request.getCookies();
            if (cookies != null && cookies.length > 0) {
                for (Cookie c : cookies) {
                    out.println(c.getName() + ": " + c.getValue());
                    out.println("<br>");
                }
            } else {
                out.println("No cookie,now creating...");
                //1.创建一个Cookie对象
                Cookie cookie = new Cookie("name", "byron");
                
                //2.调用response的方法把Cookie传递给客户端
                response.addCookie(cookie);
            }
        
        %>
    </body>
    </html>

    6. 会话 cookie 和 持久 cookie

      1.如果创建了一个 cookie, 并将其发送到浏览器,默认情况下它是一个会话级别的 cookie;存储在浏览器的内存中,用户退出浏览器之后被删除。

      2.若希望浏览器将该 cookie 存储在硬盘上,则需要设置MaxAge最大时效(单位为秒的时间值),此为持久 cookie。

      ① 将最大时效设为0则是命令浏览器删除该 cookie。

      ② 如果设置了过期时间,浏览器就会把 cookie 保存到硬盘上,关闭浏览器后再次打开,cookie 依然有效直到设定的超时时间

      ③ 持久 cookie可以在不同的浏览器进程间共享。

    7. cookie 的作用范围

      cookie 可以作用于当前目录及其子目录,但不能作用于当前目录的上一级目录。

      例:假设在 WebContent 目录下有文件 cookieWrite.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
        <%
            // cookie 可以作用于当前目录及其子目录,但不能作用于当前目录的上一级目录。
            Cookie cookie = new Cookie("cPath", "value");
            response.addCookie(cookie);
        %>
        
        <a href="path/cookieRead.jsp">To Read Cookie Page</a>
    </body>
    </html>
    View Code

           WebContent下有 path/cookieRead.jsp子目录及文件

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
        <%
            Cookie[] cookies = request.getCookies();
            if (cookies != null && cookies.length > 0) {
                for (Cookie c : cookies) {
                    if ("cPath".equals(c.getName())) {
                        out.println(c.getValue());
                    }
                }
            }
        %>
    
    </body>
    </html>
    View Code

    则cookieRead.jsp页面上是可以显示cookie的值。

    若将 cookieWrite.jsp 和 cookieRead.jsp 的路径互换,且cookieWrite.jsp内修改如下,则无法显示cookie的值。

    <a href="../cookieRead.jsp">To Read Cookie Page</a>
    View Code

      解决方法:设置cookie的作用范围

    <%
        Cookie cookie = new Cookie("cPath", "value");
    // 设置作用范围 cookie.setPath(request.getContextPath()); response.addCookie(cookie);
    %>

     

  • 相关阅读:
    ffmpeg通过组播udp推ts流
    C# 多线程总结
    《图解HTTP》6-首部
    官网下载Java连接MySql驱动jar包
    FineReport——JDBC 连接 MySQL 数据库
    serializeArray()方式请求,php获取的方法
    win10无线wifi总是掉线断网
    C# Post请求中Json格式写法
    Layui upload 上传有进度条
    java 基于redis分布式锁
  • 原文地址:https://www.cnblogs.com/techroad4ca/p/5536332.html
Copyright © 2020-2023  润新知