Cookie和Session

Posted carle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cookie和Session相关的知识,希望对你有一定的参考价值。

会话技术

一次会话中包含多次请求和响应:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止

功能:在一次会话的范围内的多次请求间,共享数据

方式:

  1. 客户端会话技术:Cookie
  2. 服务端会话技术:Session

概念

客户端会话技术,将数据保存到客户端

使用步骤

  1. 创建Cookie对象,绑定对象:Cookie(String name,String value)

  2. 发送Cookie对象:void response.addCookie(Cookie cookie)

  3. 获取Cookie,拿到数据:Cookie[] request.getCookies()

实现原理

基于响应头set-cookie和请求头cookie实现

Cookie的细节

  1. 一次可不可以发送多个Cookie?

    答:可以

  2. Cookie在浏览器中保存多长时间?

? 答:默认情况下,当浏览器关闭后,Cookie数据被销毁;

? 持久化存储:setMaxage(int seconds)

? 正数:将Cookie数据写到硬盘的文件中,单位为秒,到了时间会自动删除

? 负数:默认值

? 零 :删除Cookie信息

  1. Cookie能不能存中文?

    答:在Tomcat8之前,Cookie中不能直接存储中文数据,在Tomcat8之后,Cookie支持中文数据

    将数据中文转码的方式:一般采用URL编码(%E3)

    而且Cookie中不能存特殊符号,例如空格等,若是要使用,则需要编码和解码,如下所示

    URLEncoder.encoder("要编码的字符串","编码方式");
    举例:
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
    String format = simpleDateFormat.format(new Date());
    format = URLEncoder.encode(format,"utf-8");
    ***********************************************************************************
    URLDecoder.decoder("要解码的字符串","解码方式");
    举例:
    lastName = URLDecoder.decode(lastName, "utf-8");
  2. Cookie共享问题?

    答:一个Tomcat服务器中,部署了多个项目,那么在这些项目中Cookie数据默认不能共享

    ? setPath(String path):设置Cookie的获取范围。默认情况下,设置当前的虚拟目录,如果设置其他的目录,则只能在设置的目录中获取当前的Cookie信息。

    ? 若是需要所有的项目都能共享当前Cookie信息,则写成setPath(“/”)即可。

    ? 如果不同的服务器之间需要共享Cookie信息,则前提是一级域名相同的情况下,例如使用setDomain(“.baidu.com”),那么tieba.baidu.com和news.baidu.com中的Cookie就能共享。

Cookie特点

  1. Cookie存储数据在客户端浏览器
  2. 浏览器对于单个Cookie的大小有限制(4kb),以及对于同一个域名下的总Cookie数量也有限制(20个)

Cookie作用

  1. Cookie一般用于存储少量的不太敏感的数据
  2. 在不登录的情况下,完成服务器对客户端的身份识别

案例:利用Cookie记录用户上次登录时间

package cn.web.servlet;

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;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet("/cookiesLogin")
public class CookiesServletDemo4 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 设置响应的编码格式
        resp.setContentType("text/html;charset=utf-8");
        Cookie[] cookies = req.getCookies();
        // 初始化时间字符串
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String format = simpleDateFormat.format(new Date());
        // 因为时间模板中包含空格,会报错,所以用URL编码
        format = URLEncoder.encode(format,"utf-8");
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                if ("lastName".equals(name)) {
                    // 已经登录过
                    String lastName = cookie.getValue();
                    lastName = URLDecoder.decode(lastName, "utf-8");
                    cookie.setValue(format);
                    // 设置Cookie存活时间为一个月
                    cookie.setMaxAge(60*60*24*30);
                    // 修改值后需要重新添加(具体原因还未明白)
                    resp.addCookie(cookie);
                    resp.getWriter().write("<h3>欢迎回来,您上次访问的时间为:" + lastName + "</h3>");
                    return;
                }
            }
        }
        // 首次登录
        Cookie c = new Cookie("lastName", format);
        // 设置Cookie存活时间为一个月
        c.setMaxAge(60*60*24*30);
        resp.addCookie(c);
        resp.getWriter().write("<h3>您好,欢迎您首次访问!</h3>");
    }
}

Session

概念

服务端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中

使用步骤

  1. 获取Session对象:HttpSession session request.getSession();

  2. 使用Session对象:

    ? void setAttribute(String name, Object value);

    ? Object getAttribute(String name);

原理

Session的实现是依赖于Cookie的

细节

  1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?

    答:默认情况下,不是。

    若是需要获取同一个session,则可以创建Cookie,键为”JSESSION“,值为session.getId(),设置最大存活时间,让Cookie持久化保存(保存到硬盘上)。

    package cn.web.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.*;
    import java.io.IOException;
    
    @WebServlet("/sessionServletDemo1")
    public class SessionServletDemo1 extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            HttpSession session = req.getSession();
            Cookie c = new Cookie("JSESSIONID",session.getId());
            // 务必设置Cookie的存活时间,因为Session依赖于Cookie
            c.setMaxAge(60*60*24);
            resp.addCookie(c);
        }
    }
  2. 当客户端不关闭,服务器关闭,两次获取的session是同一个吗?

    答:几乎不一样,最好确保数据能在其中不丢失。

  3. session的失效时间?

    • 服务器关闭
    • session对象调用invalidate()自行结束
    • session默认失效时间为30分钟(可以选择性配置修改)

    技术图片

    这个文件在本机下载的Tomcat中conf目录下

特点

  1. session用于存储一次会话的多次请求的数据,存在服务器端
  2. session可以存储任意类型、任意大小的数据

Session和Cookie的区别

  • Session存储数据在服务器端,Cookie存储在客户端
  • Session没有数据大小限制,Cookie有限制
  • Session数据比Cookie相对于更安全

以上是关于Cookie和Session的主要内容,如果未能解决你的问题,请参考以下文章

少部分手机浏览器对于COOKIE支持不够导致服务端无法读取session的解决方案

Cookie和Session的工作流程及区别(附代码案例)

cookie和session

cookie和session

cookie和session

会话技术知识点整理(Cookie和Session)