JavaWeb之Cookie&&Session详解

会话

用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。

保存会话数据的两种技术

  • Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
  • Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他web资源时,其他web资源再从用户各自的session中取出数据为用户服务。

Cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。cookie原理:

这里写图片描述
浏览器第一次访问服务器时,没带有cookie,访问完Servlet1之后带有cookie信息回送给浏览器,存在缓存区。当浏览器第二次访问服务器时就已经带着缓存中的Cookie了,Servlet2此时就知道用户原本购买的信息了。

我们先看一下官方文档的对于Cookie的介绍。
这里写图片描述

javax.servlet.http.Cookie创建一个Cookie,response接口也定义了一个addCookie方法,它用于在其响应头中增加一个相应的SetCookie头字段。同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。Cookie类方法:

  • public Cookie(String name, String value) //构造方法
  • setValue getValue
  • setMaxAge getMaxAge //设置Cookie有效期,不调这个方法 Cookie有效期是浏览器进程周期(用户打开浏览器到用户关闭浏览器)
  • setPath getPath //Cookie的有效目录 默认的有效路径是哪个Servlet发出去的就是哪个servlet下的目录
  • setDomain getDomain // 设置域 如 .sina.com.cn
  • getName

Cookie的应用:获取最近访问时间,与清除Cookie

  • 创建模拟网站首页的Servlet,
package com.xuda27.cookie;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
 * 代表网址首页
 */
public class CookieTest1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //服务器向浏览器发送数据 编码以utf-8格式
        response.setCharacterEncoding("utf-8");
        //通知浏览器以utf-8打开数据
        response.setContentType("text/html charset=utf-8");
        PrintWriter out = response.getWriter();

        out.print("<a href='/JavaWeb_CookieSession/servlet/CookieTest2'>清除Cookie</a><br>");

        out.print("您上次访问时间是:");

        //获得用户的时间cookie
        Cookie []cookies = request.getCookies();
        for(int i=0;cookies!=null && i<cookies.length;i++){
            if(cookies[i].getName().equals("lastAccessTime")){
                //得到用户上次访问时间
                long cookieValue = Long.parseLong(cookies[i].getValue());
                Date date = new Date(cookieValue);
                out.print(date.toLocaleString());
            }
        }


        //给用户回送最新的访问时间
        //创建名为 lastAccessTime,值为系统当前时间的Cookie
        Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");
        cookie.setMaxAge(30*24*3600);//cookies有效期 30天
        cookie.setPath("/JavaWeb_CookieSession");//设置cookie的有效路径:当前工程
        response.addCookie(cookie);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    }

}

后台处理servlet:

package com.xuda27.cookie;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 后台清除Cookie 
 * @author eden
 *
 */
public class CookieTest2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //Cookie与前面的要长得一样
        Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");
        cookie.setMaxAge(0);//清除
        cookie.setPath("/JavaWeb_CookieSession");//路径要设置一样
        response.addCookie(cookie);//浏览器增加空的cookie

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

测试结果:
这里写图片描述

我们打开firebug可以看到Cookie信息。
这里写图片描述

当我第一次访问CookieTest1(代表网站首页)时,没有带有Cookie信息所以就没有显示上一次访问的时间,然后Servlet才创建Cookie信息,然后在当我刷新页面时,Servlet就会发现有Cookie信息,这时就把上一次访问的时间给显示出来。当点击清除Cookie时,跳转到cookieTest2(代表后台处理),此时Servlet创建一个空的Cookie将原来Cookie信息覆盖,所以当我再一次访问CookieTest1时,上一次访问时间就没有了。

Cookie的一些细节

  1. 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置(VALUE)。
  2. 一个Web站点可以给一个web浏览器发送多个Cookie,一个Web浏览器可以存储多个web站点提供的Cookie。
  3. 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
  4. 如果创建了一个cookie,并将它发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要是要maxAge,并给出一个以秒为单位的时间。将最大时间设为0则是命令浏览器删除该cookie。
  5. 注意,删除Cookie时,path必须一致,否则不会删除

Session

Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,用户可以在访问服务器的web资源时,可以把各自的数据放在各自的session中,所以session跟ServletContext和Request一样也是域对象。当用户再去访问服务器中的其它web资源时,其它web资源就可以从用户各自的session中取出数据为用户服务。

Session的生命周期

Session域的作用范围是:默认情况下是在一个会话期间,当然这个范围我们是可以设置的,设置之后可以在多个会话之间。那么Session的生命周期是:
1. Session什么时候创建:
Servlet调用HttpServletRequest.getSession(true)这样的语句时才会被创建。
2. Session什么时候销毁:
Session在下列情况下被删除:

  • 程序调用HttpSession.invalidate()
  • 距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
  • 服务器进程被停止

再次注意关闭浏览器只会使存储在客户端浏览器内存中的session的cookie失效,不会使服务器端的session对象失效。

Session实现原理

服务器创建session出来后,会把session的id号,以cookie的形式回写给浏览器,这样,只要浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现浏览器带session id过来了,就会使用内存中与之对应的session为之服务。

图解:

Session实现原理

浏览器访问Servlet1时,通过调用request.getSession()方法判断服务器中是否含有该session,如果没有则创建,如果有直接调用。因为第一次调用则创建session,并获取session的id,将这个id以Cookie形式会写给浏览器。当浏览器带着Cookie访问servlet2时,调用request.getsession 服务器发现服务器端的session id与cookie的值是否相同,相同直接为它服务。

内部原理,用代码实现 类似这样:

//获取session的Id
String sessionId = session.getId();
//将session的Id存储到名字为JSESSIONID的cookie中
Cookie cookie = new Cookie("JSESSIONID", sessionId);
//设置cookie的有效路径
cookie.setPath(request.getContextPath());
response.addCookie(cookie);

Session的相关API

  • getAttribute(String name)/getAttributeNames()/setAttribute(String
    name)/removeAttribute(String name) 这些方法都是和Session域中的值有关的方法,和ServletContext,Request域的是一样
  • getCreationTime():获取Session的创建时间
  • getId():获取session的id
  • getServletContext():获取ServletContext对象,即jsp中的application
  • invalidate():删除session,然后取消对任何绑定到它的对象的绑定。
  • setMaxInactiveInterval(int interval):这个方法设置session的最大有效时间,以秒为单位。负数时间指示session永远不会超时。

修改session默认生命周期:

        HttpSession session = request.getSession();
        String sessionId = session.getId();
        Cookie cookie = new Cookie("JSESSIONID", sessionId);

        cookie.setPath("/JavaWeb_CookieSession");//设置session的有效路径,覆盖默认的session的路径
        cookie.setMaxAge(30*60);//设置时长为30分钟
        response.addCookie(cookie);

        session.setAttribute("name", "你好!世界!");

取出session中的值:

        resp.addHeader("content-type", "text/html;charset=utf-8");
        resp.setCharacterEncoding("utf-8");
        PrintWriter out = resp.getWriter();

        String name = (String) req.getSession().getAttribute("name");
        out.print(name);

如果浏览器禁用Cookie中就无法使用上面的代码来取得存在Cookie中的session id,无法与服务器中的session id匹配。

所以在浏览器禁用Cookie时,怎么来解决session的数据共享问题呢?

  • response.encodeRedirectURL(java.lang.String url)
    用于对sendRedirect方法后的url地址进行重写。
  • response.encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
        response.addHeader("content-type", "text/html;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();

        //创建session
        request.getSession();

        //会在原有的url后面加上 JSESSIONID 地址重写
        String url1 = response.encodeURL("/JavaWeb_CookieSession/servlet/SessionTest1");
        String url2 = response.encodeURL("/JavaWeb_CookieSession/servlet/SessionTest2");

        out.print("<a href='"+url1+"'>说</a><br>");
        out.print("<a href='"+url2+"'>看</a>");

在禁用Cookie之后,这两个方法会给地址重写。

这里写图片描述

它会在原有的地址后面加上 session id号。而如果不禁用Cookie则超链接的地址则不会重写。

Session和Cookie的主要区别

  • cookie是把用户的数据写给用户的浏览器。
  • session把用户的数据写到用户独占的session中。
  • session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。

三个域对象的总结

  1. 产生数据之后,显示完了就没用了,就用request。
  2. 产生数据之后,除了显示等一会还有用,就用session。
  3. 产生数据之后,除了显示等一会还要给别人用,就用servletContext。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值