Servlet之会话技术(Cookie与Session)

一、会话技术

从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,称为一次会话。会话技术就是记录这次会话中客户端的状态与数据的 

会话技术分为Cookie和Session:

Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端可以清除cookie

Session:将数据存储到服务器端,安全性相对好,增加服务器的压力

二、为什么需要会话技术?

在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。在客户端浏览器向服务器发送请求,服务器做出响应之后,二者便会断开连接(一次会话结束)。那么下次用户再来请求服务器,服务器没有任何办法去识别此用户是谁。比如web系统常用的用户登录功能,如果没有cookie机制支持,那么只能通过查询数据库实现,并且要命的是每次刷新页面都要重新输入表单信息查询一次数据库才可以识别用户,这会给开发人员带来大量冗余工作并且简单的用户登录功能会给服务器带来巨大的压力。

在此背景下,就急需一种机制来解决此问题。分析可知,以上需求的实现就要客户端每次访问服务器时从客户端带上一些数据(相当于身份证)告知服务器自己是谁。这个数据就是cookie!

那么有了cookie,为什么还要有session呢?有了cookie可以向服务器证明用户身份了,我们的web系统中是不是需要将用户的详细信息储存在某个位置供页面调用呢?用户的详细信息就包括姓名,年龄,性别等信息。而cookie是存在于客户端的,将用户详细信息通过网络发送到客户端保存是极不安全的。且cookie大小不能超过4k,不能支持中文。这就限制cookie不能满足存储用户信息的需求。这就需要一种机制在服务器端的某个域中存储一些数据,这个域就是session。

总而言之,cookie/session的出现就是为了解决http协议无状态的弊端,为了让客户端和服务端建立长久联系而出现的。

三、Cookie

1.概念

在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。

Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一服务器,是在客户端保持状态的方案。

执行流程:

当你去访问应用的时候,来到服务器。服务器设置一个cookie,在做响应的时候会通过set-cookie响应头将cookie带给浏览器。来到浏览器,浏览器会将此数据保存起来,接下来再次去访问服务器的时候,浏览器会根据cookie的path属性将这些数据带回去(设置了一个叫做cookie的请求头),来到服务器,服务器有对应的api获取这些值,有了值就知道用户是谁了。

2.服务端向客户端发送一个Cookie

(1)创建Cookie

    Cookie cookie = new Cookie(StringcookieName,String cookieValue);

示例:  Cookie cookie = new Cookie("username","mark");

那么该cookie会以响应头的形式发送给客户端:   Set-Cookie:"name=mark"

(2)设置Cookie在客户端的持久化时间

    cookie.setMaxAge(int seconds); //时间秒

注意:如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭 cookie信息销毁(会话级别的cookie),如果设置持久化时间,cookie信息会被持久化到浏览器的磁盘文件里

               示例:   cookie.setMaxAge(10*60);

               设置cookie信息在浏览器的磁盘文件中存储的时间是10分钟,过期浏览器自动删除该cookie信息

(3)设置Cookie的携带路径

    cookie.setPath(String path);

注意:如果不设置携带路径那么该cookie,信息会在访问产生该cookie的web资源所在的路径都携带cookie信息

                示例:cookie.setPath("/web");                             代表访问web应用中的任何资源都携带cookie

                          cookie.setPath("/web/cookieServlet");       代表访问web中的cookieServlet时才携带cookie信息

                          cookie.setPath("/");                                     代表服务器下所以资源都携带cookie信息

(4)向客户端发送cookie

    response.addCookie(Cookie cookie);

(5)删除客户端的cookie

如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时间为0的cookie进行覆盖即可

3.服务器端接受客户端携带的Cookie

cookie信息是以请求头的方式发送到服务器端的Cookie:"name=mark"

    //通过request获得所有的Cookie
    Cookie[] cookies = request.getCookies();
    //遍历Cookie数组,通过Cookie的名称获得我们想要的Cookie
    for(Cookie cookie : cookies){
        if(cookie.getName().equal(cookieName)){
            String cookieValue = cookie.getValue();
        }
    }

4.案例

    protected void doGet(HttpServletRequest request, HttpServletResponse response){
        response.setContentType("text/html;charset=utf-8");
        String userName = request.getParameter("username");
        String password = request.getParameter("password");
		
        if("admin".equals(userName) && "123".equals(password)){
            //获取cookie last-name --- >
            Cookie [] cookies = request.getCookies();
			
            //从数组里面找出我们想要的cookie
            Cookie cookie = CookieUtil.findCookie(cookies, "last");
			
            //是第一次登录,没有cookie
            if(cookie == null){
				Cookie c = new Cookie("last", System.currentTimeMillis()+"");
                c.setMaxAge(60*60); //一个小时
                response.addCookie(c);
				
                response.getWriter().write("欢迎您, "+userName);
            }else{
                //1. 去以前的cookie第二次登录,有cookie
                long lastVisitTime = Long.parseLong(cookie.getValue());
				
                //2. 输出到界面
                response.getWriter().write("欢迎您, "+userName +",上次来访时间是:"+new Date(lastVisitTime));
				
                //3. 重置登录的时间
                cookie.setValue(System.currentTimeMillis()+"");
                response.addCookie(cookie);
            }
        }else{
            response.getWriter().write("登陆失败 ");
        }	
    }

四、Session

1.概念

Cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。

Session是存在服务器的一种用来存放用户数据的类HashTable结构。浏览器第一次发送请求时,服务器自动生成了一HashTable和一Session ID来唯一标识这个HashTable,并将其通过响应发送到浏览器。浏览器第二次发送请求会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的HashTable。

Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。

服务器也可以通过URL重写的方式来传递SessionID的值,因此不是完全依赖Cookie。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员透明。aaa.jsp?JSESSIONID=*

执行流程:

浏览器发起一个请求到服务器,服务器先检查你是否携带了一个叫做JSESSIONID的cookie。如果有携带,会将此cookie的值取出来(比如为aaa123),然后从服务器的session池中找到ID为aaa123的session返回给调用者。

如果没有携带这个JSESSIONID的cookie,那么服务器将会自动创建一个session对象并且生成一个随机字符串(如aaa123)作为此session的ID保存到session池中。在服务器为客户端浏览器作响应的时候自动创建一个键为“JSESSIONID” 值为“aaa123”的cookie对象让浏览器储存起来以便下次再访问的时候带过来。

2.实例

		//得到会话ID
		String id = session.getId();
		
		//存值
		session.setAttribute(name, value);
		
		//取值
		session.getAttribute(name);
		
		//移除值
		session.removeAttribute(name);

3.生命周期 

(1)创建

在servlet里面调用了 request.getSession()

(2)销毁

1'' 服务器关闭时

2'' session过期/失效(默认30分钟,从不操作服务器端的资源开始计时

过期时间可设置的,如不设,则浏览器关掉就消失了,存储在内存当中,否则就按设置的时间来存储在硬盘上的,过期后自动清除,比方说开关机,关闭再打开浏览器后它都会还存在,前者称之为Session cookie 又叫 transient cookie,后者称之为Persistent cookie 又叫 permenent cookie。

    
    
        30
     

3'' 手动销毁session(session.invalidate()

你可能感兴趣的:(Servlet)