Cookie使用细节

Cookie存活时间:

默认情况之下:

Cookie存储到浏览器的内存中, 当浏览器关闭的时候浏览器的内存就会释放, 则Cookie被销毁

  • 浏览器也是一个程序, 但程序停止运行的时候, 对应的程序的内存就会被清空
非默认情况之下:

我们可以通过setMaxAge(int seconds)方法来设置Cookie存活时间

  • 注意: 这个方法的形参位置是秒数而不是毫秒数, 我们以前的时候使用到的很多传入秒数的方法中传入的都是毫秒数
  1. seconds为正数: 将Cooke写入浏览器所在电脑的硬盘中, 持久化存储, 到时间之后自动删除
  2. seconds为负数: 将Cookie在当前浏览器内存中存储, 当浏览器关闭的时候Cookie就会被销毁
  • 默认值就是seconds为负数
  1. seconds为零 : 直接将删除对应的Cookie

Cookie存储中文出现乱码:(tomcat8之前)

Cookie是不能直接存储中文的, 如果要存储中文, 就要进行一个转码: 一般情况我们都是转为URL编码

  • 因为Cookie是基于Http协议实现的, 所以传输的时候是不能有中文数据的
  • Cookie中存储的数据只能是ACSII编码数据, 如果存储其他数据的时候要进行一个对应的编码, 一般就编码为URL或者UTF-8都是可以的
这里我们传输之前就进行了一个中文的URL在utf-8字符集下的编码
package com.ffyc.demo;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

@WebServlet("/main3")
public class MainServlet3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建Cookie对象, 设置数据
         //这个时候我们使用Cookie传输了一个中文数据, 由于我们的HTTP协议中不能直接传输中文数据, 所以我们要进行一个URL编码之后再发送
        String name = "张三";
        URLEncoder.encode(name,"utf-8"); //我们一定要是指定为utf-8编码字符集, 因为我们客户端解析的时候就是以utf-8形式的url形式对中文数据进行一个解析
        Cookie cookie = new Cookie("name",name);

        //发送cookie到客户端, 使用response对象
        resp.addCookie(cookie);
    }
}
* ##### 然后接收的时候我们也要使用utf-8形式下的URL解码方式进行一个解码

  ```java
  package com.ffyc.demo;
  
  import javax.servlet.ServletException;
  import javax.servlet.annotation.WebServlet;
  import javax.servlet.http.Cookie;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import java.io.IOException;
  import java.net.URLDecoder;
  
  @WebServlet("/main4")
  public class MainServlet4 extends HttpServlet {
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          //获取从客户端发送过来的Cookie对象[]
          Cookie[] cookies = req.getCookies();
  
          //使用增强for循环遍历cookies数组
          for (Cookie c :
                  cookies) {
              String name = c.getName();
              //判断如果是我们要查询的键的时候才继续去进入到if判断中, 获取出对应的值, 然后打印输出到控制台
              if ("name".equals(name)) {
                  //这个时候我们要对对应的URL编码值进行一个解码操作
                  String value = URLDecoder.decode(c.getValue(),"utf-8");
                  System.out.println(name + ":" + value);
              }
          }
      }
  • 那么我们要如何解决Cookie中存储中文导致的乱码问题?
  • 我们只需要将中文数据编码之后存储即可
  • 对于请求体和响应体中的数据都是使用二进制流的形式进行传输的, 对于请求体和响应体中如果有中文数据的时候我们只需要设置对应的流采用的字符集就可以了

补充:

问题遗留: 对于响应头中的数据是不需要进行转码的?(也就是对于响应头中的数据传输和响应行是不一样的) 后面深入理解

补充:

我们其实可以发现: 很多时候取值的时候如果是正数和负数之间取值的时候都是负数为默认值

  • 比如:
  1. 我们对于tomcat服务器中创建Servlet对象的时机的控制是通过的loadOnStartUp的取值来控制的, 如果是负整数就是表示对应Servlet被第一次请求的时候创建Servlet对象, 如果是非负整数(也就是0或者是正整数)的时候我们都是当服务器启动的时候Servlet对象就会随着服务器的启动而启动了
  • 这个时候loadOnStartUp取值为负数就是默认取值
  1. 我们对于Cookie对象调用setMaxAge(int seconds)方法设置Cookie的存活方式和存活时间的时候, 如果是负数就表示存储到浏览器工作内存中, 如果是正数就表示存储到客户端本地内存中, 如果是0就表示立即删除此Cookie, 默认值也是负数, 表示的是存储到浏览器工作内存中( 默认情况之下是存储到浏览器工作内存中30分钟 )
  • 这个时候setMaxAge()方法的参数为负数也是默认取值