cookie与session

cookie与session,第1张

在日常生活中,从拨通电话到挂断电话之间的一连串的你问我答的过程就是一个会话。

Web应用中的会话过程类似于生活中的打电话过程,它指的是一个客户端(浏览器)与Web服务器之间连续发生的 一系列请求和响应过程,

例如,一个用户在某网站上的整个购物过程就是一个会话。 在打电话过程中,通话双方会有通话内容,同样,在客户端与服务器端交互的过程中,也会产生一些数据。为了保 存会话过程中产生的数据,在Servlet技术中,提供了两个用于保存会话数据的对象,分别是Cookie和Session

cookie

浏览器端的会话技术,它通过在浏览器中记录一些服务器传递过来的数据,解决会话从什么时候开始,到什么时候结束。

就是在浏览器上记录会话过程中产生的临时数据。

HTTP协议是无状态协议,只定义规则,不保存数据,就有了cookie的产生。

cookie的应用场景
  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 上一次访问时间
  • 购物车
常用api
package com.lx.servlet.cookiesession;

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;

@WebServlet("/cookieSessionDemo")
public class CookieSessionDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("demoUserName","jayChou");

        // cookie路径
        // 服务器是根据路径获取cookie的,cookie默认路径是 请求路径的上一级
        // 如果默认路径为多级的话,就拿不到本网站所有的cookie
        // 所以一般我们设置项目路径为cookie的路径
        cookie.setPath(req.getContextPath());

        // cookie默认是会话级别,存储在内存中
        // 也可以设置为持久化级别,存储在硬盘
        // 单位为秒,正整数为持久化的时间,
        // 负整数,代表会话级别
        // 0 代表删除
        // 删除cookie,同名同路径,setMaxAge 为 0
        cookie.setMaxAge(60*60*24*7);

        // 向浏览器添加cookie
        resp.addCookie(cookie);


        Cookie[] cookies = req.getCookies();

        // 这个获取所有cookie只是获取本网站的cookie,而不是浏览器的所有cookie
        if (cookies!=null && cookies.length > 0){
            for (Cookie cookieObj : cookies) {
                System.out.println(cookieObj.getName() + ":" +cookieObj.getValue());
            }
        }


    }
cookie注意事项
  • 不支持中文
  • 不能跨浏览器
  • 有大小限制,4kb
  • 对于一个网站,最多20个cookie
session

在服务器端的会话技术,session是一个域对象,代表一次会话,这种会话可以是持续的,也可以是断续的。

package com.lx.servlet.cookiesession;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/cookieSessionDemo")
public class CookieSessionDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 如果浏览器第一次访问服务器,就会创建一个session对象
        // 服务器会自动创建一个cookie 名字是 JSESSIONID
        HttpSession session = req.getSession();

        session.setAttribute("sessionUserName","jay");

        // 服务器创建session后会有一个随机的id
        String id = session.getId();

        Cookie cookie = new Cookie("JSESSIONID", id);

        // 将session设置失效时间为7天
        cookie.setMaxAge(60*60*24*7);
        cookie.setPath(req.getContextPath());

        resp.addCookie(cookie);


        resp.setContentType("text/html;charset=utf-8");

        String sessionUserName = (String) session.getAttribute("sessionUserName");
        resp.getWriter().write("名字是:" + sessionUserName);


    }

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

session应用场景

Session 代表着服务器和客户端一次会话的过程。

Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。

cookie和session的区别
  1. 存储位置不同
  • cookie的数据信息存放在客户端浏览器上
  • session的数据信息存放在服务器上
  1. 存储容量不同
  • 单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie
  • 对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西
  1. 隐私策略不同
  • cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的
  • session存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的风险
  1. 性能使用不同
  • session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
cookie与session生命周期

cookie默认的生命周期为会话级别,可以手动设置为持久化。

Tomcat中默认是30分钟, 在tomcat的conf/web.xml中有如下配置

<session-config>  
        <session-timeout>30session-timeout>  
session-config>  

这个30分钟是指距最后一次访问30分钟

为什么需要 Cookie 和 Session,他们有什么关联?

说起来为什么需要 Cookie ,这就需要从浏览器开始说起,我们都知道浏览器是没有状态的(HTTP协议无状态),这意味着浏览器并不知道是张三还是李四在和服务端打交道。

这个时候就需要有一个机制来告诉服务端,本次 *** 作用户是否登录,是哪个用户在执行的 *** 作,那这套机制的实现就需要 Cookie 和 Session 的配合。

用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建创建对应的 Session ,请求返回时将此 Session 的唯一标识信息SessionID 返回给浏览器,浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时Cookie 记录此 SessionID 属于哪个域名。

当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie
信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session
信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面 *** 作。

根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

服务端是根据 Cookie 中的信息判断用户是否登录,那么如果浏览器中禁止了 Cookie,如何保障整个机制的正常运转
  1. 第一种方案,每次请求中都携带一个 SessionID 的参数,也可以 Post 的方式提交,也可以在请求的地址后面拼接xxx?SessionID=123456…。

  2. 第二种方案,Token 机制。Token 机制多用于 App 客户端和服务器交互的模式,也可以用于 Web 端做用户状态管理。
    Token 的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。Token 机制和 Cookie 和Session的使用机制比较类似。
    当用户第一次登录后,服务器根据提交的用户信息生成一个 Token,响应时将 Token 返回给客户端,以后客户端只需带上这个 Token前来请求数据即可,无需再次登录验证

todo session共享的事情还没有好好看,有时间再说吧

session共享

有好几种,这里只说最常用,最可靠的一种

在单独的服务器或服务器集群上使用缓存技术,如Redis存储Session数据,集中管理所有的Session,所有的Web服务器都从这个存储介质中存取对应的Session,实现Session共享。

优点:可靠性高,减少Web服务器的资源开销。

缺点:实现上有些复杂,配置较多。

适用场景:Web服务器较多、要求高可用性的情况。

分布式中解决session共享方案 tomcat redis方案

tomcat与redis集成实现session共享:
环境为tomcat7 + jdk1.6的话:
在所有需要共享session的服务器的tomcat中目录下:
lib目录中添加以下三个jar包,注意版本最好一致,不然极容易出现错误,下边的测试是可用的:


conf目录中content.xml中加入:配置redis服务


修改content.xml

添加两个注意点
1、按照如上配置,使用redis数据库,放入session中的对象必须要实现java.io.Serializable接口,使用memcache的可以不用实现Serializable接口
原因是:因为tomcat里使用的将session放置redis使用的工具类,是使用的jdk序列化模式存储的,这一点也是很容易理解的,session.setAttribute(String key, Object value),存储Object类型
object放入redis中又要能取出来,只能是序列化进行存储了,然后取出的时候进行反序列化。
所以我们在session中存储的任何对象,都必须实现序列化接口。
2、按照如上配置,使用redis做session存储空间时,web应用的session-time的时间单位会变成[秒],而不是原本的[分]
原因是:因为tomcat里使用的将session放置redis使用的工具类,在存储时为对tomcat容器时间做转换
在redis中设置过期时间是使用秒作为单位的,有个命令叫expire可以设置redis键值过期时间,所以在context.xml配置文件中我们需要制定session过期时间(默认是60秒,配成1800即30分钟),这一点很重要。
请注意!!!!
context.xml配置说明:
在这里插入图片描述

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/922305.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存