会话管理者--Cookie&Session

在访问网站的时候,肯定不止一个用户,那么对于不同的用户,服务器是如何区分的呢?

Cookie,是一种客户端技术,服务器将每个用户的信息以Cookie的形式保存在用户各自的客户端,之后客户端向服务器发送请求的时候,便携带属于自己的Cookie,那么服务器就能因此处理用户各自的数据

Cookie的使用:

  • 1.从request对象中获取Cookie

    Cookie[] cookies = request.getCookies();
    
  • 2.getName()获得Cookie的属性名

    String name = cookies[i].getName();
    
  • 3.getValue()获得Cookie属性名对应的值

    String value = cookies[i].getValue();
    
  • 4.创建Cookie

    Cookie cookie  = new Cookie(name,value);
    
  • 5.设置Path,即Cookie存储的路径

    cookie.setPath(url);
    假设URL:http://localhost:8090/Dreams/cookie/ck1
    其中应用的根目录是/Dreams
    如果不设置Path,那么默认存储的路径是/Dreams/cookie
    那么,只有/Dreams/cookie及其子文件目录下的Servlet才能获取到Cookie,如下地址http://localhost:8090/Dreams/ck2是获取不到的;
    通常设置的Path为应用的根目录,那么该应用下的所有请求都可以获得Cookie的值。以下三种方式均可以实现该设置
    cookie.setPath("/Dreams"); // 不够灵活,如果应用名称改变,则需要手动修改Path的设置
    cookie.setPath(request.getPath());  
    cookie.setPath("/");
    
  • 6.设置Cookie的有效时间,其中时间是以s为单位

    cookie.setMaxAge(time);
    如果不设置有效时间,默认的有效时间是会话级别的,即存储在浏览器的内存中,浏览器一旦被关闭,则本次会话结束,Cookie就被删除;若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,此时即使用户关闭了浏览器,在设定的时间之内,Cookie是有效的;将最大时效设为0,则是命令浏览器删除该cookie,注意删除的时候要保证路径一致,否则不会删除;删除后如果会话没有关闭,而且之前设置了存储到硬盘上,那么Cookie也是会存在的。如果为负数,则表示不存储该 cookie。默认的是复数,即不往硬盘上存储Cookie。
    
  • 7.将Cookie写回客户端

    response.addCookie(cookie);
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException{
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        //从request对象中获取Cookie
        Cookie[] cookies = request.getCookies();
        for(int i=0;cookies!= null && i<cookies.length;i++){
        //getName()获得Cookie的属性名
            if("currentTime".equals(cookies[i].getName())){
               //getValue()获得Cookie属性名对应的值
               long l = Long.parseLong(cookies[i].getValue());
                writer.println("上次访问时间:"+new Date(l).toLocaleString());
            }
        }
        //创建Cookie
        Cookie cookie = new Cookie("currentTime",System.currentTimeMillis()+"");
        //设置Cookie的有效时间
        cookie.setMaxAge(60*5);
        //设置Cookie的path,以下三种设置方式的结果是一样的,都是将Cookie保存在应用的根目录下,这样根目录下及其子文件夹都能访问到该Cookie
        //cookie.setPath("/Dreams");
        cookie.setPath("/");
        //cookie.setPath(request.getContextPath());
        //将Cookie写回客户端
        response.addCookie(cookie);
    }

删除Cookie:

        Cookie ck = new Cookie("currentTime","");
        ck.setPath("/"); //设置被删除Cookie的Path,否则可能删除失败
        //设为0表示删除Cookie
        ck.setMaxAge(0);
        response.addCookie(ck);

即使是同一个浏览器,不同的会话打开同一个应用,如果不进行Cookie的设置,那么每个会话会建立各自的Cookie,只有将Cookie存入硬盘,且设置路径为当前应用,则同一个应用的两个不同会话才能访问到同一个Cookie

Session,也具有跟Cookie类似的功能,不过最主要的区别在于Session是一种服务器技术,有关每一个用户的信息是保存在服务器Session对象中的。一个浏览器独占一个Session对象

那么问题来了,服务器端为每一个用户建立了一个Session对象保存信息,但是当客户端向服务器发起请求时,Servlet中都是通过request.getSession()方法获得Session对象,对于不同的用户,服务器是如何区分并取出与之相对应的Session对象呢?
这是因为服务器的每个Session对象有一个唯一的SessionID编号,当服务器针对每个用户创建Session对象同时将该Session对象的SessionID写入Cookie传递给浏览器保存在客户端,之后用户向服务器发送请求的时候,浏览器会将Cookie一并发送给服务器,此时服务器通过从Cookie中取SessionID的值,即可找到属于该用户的Session对象。Session是依赖于Cookie技术的。

//获得Session对象
request.getSession();

上述语句获得Session对象的原理:
1. 获取名称为JSESSIONID的Cookie的值
2. 如果没有这样的Cookie,则创建一个新的Session对象,分配唯一的SessionID,并向客户端写一个SessionID=JSESSIONID的Cookie;如果有这样的Cookie,则获取到SessionID的值,从服务器内存中根据获得的ID找到HttpSession对象。
3. 如果找到Session对象,则取出为你服务;如果没有找到,则从步骤2开始

Session对象常用方法:
1. void setAttribute(String name,Object value);
2. Object getAttribute(String name);
3. void removeAttribute(String name);
4. HttpSession.getId():
5. setMaxInactiveInterval(int interval) 设置session的存活时间,以s为单位
6. invalidate() 使此会话无效。通常用户点击退出登录操作时,调用该方法,使得Session无效。

Session的状态:

要想持久化存储,那么存储的对象必须可序列化,即需要实现Serializable接口



我们知道Session是依赖于Cookie的,那么如果客户端禁用Cookie了,那么该怎么办?
解决方式,URL重写,每次请求的URL保存JSESSIONID信息

  • response. encodeRedirectURL(java.lang.String url)

    用于对sendRedirect方法后的url地址进行重写。
    
  • response. encodeURL(java.lang.String url)

     用于对表单action和超链接的url地址进行重写。
     (通过将会话 ID 包含在指定 URL 中对该 URL 进行编码,如果不需要编码,则返回未更改的 URL。此方法的实现包含可以确定会话 ID 是否需要在 URL 中编码的逻辑。例如,如果浏览器支持 cookie,或者关闭了会话跟踪,则 URL 编码就不是必需的。对于健壮的会话跟踪,servlet 发出的所有 URL 都应该通过此方法运行。否则,URL 重写不能用于不支持 cookie 的浏览器)
    

    问题补充:

    面试问题:
    如果客户端Cookie禁用了,那么Session还能用么?
    答案是可用可不用,原本Session的使用依赖于Cookie,那么Cookie被禁用后,那么Session使用Cookie的方式便行不通了, 不过我们可以对URL地址进行重编码,那么JSESSIONID就随着浏览器请求的URL传给服务器,Session依旧是可以使用的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值