cookie&session

1.会话技术
1.1会话技术概述

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

1.2 会话技术的分类

(1)cookie:

    Cookie是客户端技术,翻译成中文是小甜点。在HTTP中它表示服务器送给客户端浏览器的小甜点。其实Cookie就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了。

(2)session:

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

2.cookie
2.1 cookie概述

         Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。Cookie名称和值可以由服务器端开发自己定义,对于JSP而言也可以直接写入jsessionid,这样服务器可以知道该用户是否合法用户以及是否需要重新登录等,服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。


2.2 cookie与Http协议

(1)cookie与http协议关系

    Cookie是Http协议制定的,并不是Java语言独有的,PHT、.NET中也使用了cookie技术,因此只要是和HTTP协议相关,那么就可以使用cookie技术。

    cookie是服务器创建的一个键值对,并保存在浏览器端。在服务器端先创建cookie,如 Cookie cookie=newCookie(String name,String value),其中Cookie可以在javaeeAPI中查到的,详情可参考java_ee API。然后再通过response对象将cookie信息作为响应头发送到浏览器端。我们可以通过抓包工具查看响应信息,可以发现cookie是基于一个Set-Cookie响应头工作的,由于Set-Cookie响应头可以有多个,所以我们可以通过response.addHeader(Stringname,String value)方法发送Set-Cookie响应头,例如,有两个cookie,分别为one=aaa,two=bbb,其中one、two是cookie的名称,aaa、bbb是cookie的值。发送响应头如下所示:

    response.addHeader(“Set-Cookie”,”one=aaa”);

    response.addHeader(“Set-Cookie”,”two=bbb”);

    当浏览器再次访问服务器时,会将cookie送还给服务器。浏览器通过Cookie请求头传递过去,请求头Cookie与响应头Set-Cookie有区别,多个cookie对应多个Set-Cookie响应头,但是只对应一个Cookie请求头,格式为:Cookie:one=aaa; two=bbb。即多个cookie之间用分号和空格隔开。

需要注意的是:cookie是不能跨浏览器的。例如,张三首先使用IE浏览器访问服务器,服务器发送了一个cookie,这个cookie只会保存在IE浏览器,如果再使用火狐浏览器访问服务器,服务器会再发送一个cookie个火狐浏览器,在火狐浏览器中不能获取IE浏览器中的cookie,同理IE浏览器也获取不到火狐浏览器中的cookie。

(2)http协议规定

    Http协议对Cookie做了一些规定,如下所示:

    a.   一个Cookie的大小,最大为4KB;

    b.   一个服务器最多向一个浏览器保存20个Cookie;

    c.    一个浏览器最多可以保存300个Cookie。

2.3 cookie常用方法

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

构造方法:

    public  Cookie(String name, String value):构造带指定名称和值的 cookie。

成员方法:

    public  String  getName():返回 cookie 的名称

    public  String  getValue():返回 cookie 的值。

    public  void  setMaxAge(int expiry):设置 cookie 的最大生存时间,以秒为单位

    public  void  setPath(String uri):指定客户端应该返回 cookie 的路径。

        

第一次请求和响应信息:

        

第二次请求与响应信息:


2.4 cookie的持久化

        如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用Cookie类的setMaxAge方法,并给出一个以秒为单位的时间。

    (1)cookie.setMaxAge(-1):cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。

    (2)cookie.setMaxAge(60*60):表示cookie对象可存活1小时。当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie也会存活1小时;

    (3)cookie.setMaxAge(0):cookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。

2.5cookie的路径

    (1)什么是Cookie的路径

        WEB应用A,向客户端发送了10个Cookie,这就说明客户端无论访问应用A的哪个Servlet都会把这10个Cookie包含在请求中!但是也许只有AServlet需要读取请求中的Cookie,而其他Servlet根本就不会获取请求中的Cookie。这说明客户端浏览器有时发送这些Cookie是多余的!可以通过设置Cookie的path来指定浏览器,在访问什么样的路径时,包含什么样的Cookie。

    (2)Cookie路径与请求路径的关系

    Cookie路径的作用:

        下面是客户端浏览器保存的3个Cookie的路径:

        a:/cookietest;

        b:/cookietest/servlet;

        c:/cookietest/jsp;

 

        下面是浏览器请求的URL:

        A:http://localhost:8080/cookietest/AServlet;

        B:http://localhost:8080/cookietest/servlet/BServlet;

        C:http://localhost:8080/cookietest/jsp/CServlet;

        请求A时,会在请求中包含a;

        请求B时,会在请求中包含a、b;

        请求C时,会在请求中包含a、c;

          也就是说,请求路径如果包含了Cookie路径,那么会在请求中包含这个Cookie,否则不会请求中不会包含这个Cookie。

               A请求的URL包含了“/cookietest”,所以会在请求中包含路径为“/cookietest”的Cookie;

     B请求的URL包含了“/cookietest”,以及“/cookietest/servlet”,所以请求中包含路径为“/cookietest”和“/cookietest/servlet”两个Cookie;

     B请求的URL包含了“/cookietest”,以及“/cookietest/jsp”,所以请求中包含路径为“/cookietest”和“/cookietest/jsp”两个Cookie;

    (3)设置Cookie的路径

        设置Cookie的路径需要使用setPath()方法,例如:

        cookie.setPath(“/cookietest/servlet”);

 

    如果没有设置Cookie的路径,那么Cookie路径的默认值当前访问资源所在路径,例如:

    访问http://localhost:8080/cookietest/AServlet时添加的Cookie默认路径为/cookietest;

    访问http://localhost:8080/cookietest/servlet/BServlet时添加的Cookie默认路径为/cookietest/servlet;

    访问http://localhost:8080/cookietest/jsp/BServlet时添加的Cookie默认路径为/cookietest/jsp;

2.6 Cookie中保存中文

        Cookie的name和value都不能使用中文,如果希望在Cookie中使用中文,那么需要先对中文进行URL编码,然后把编码后的字符串放到Cookie中。

(1)向客户端响应中添加Cookie

        String name = URLEncoder.encode("姓名", "UTF-8");

       String value = URLEncoder.encode("张三", "UTF-8");

       Cookie c = new Cookie(name, value);

       c.setMaxAge(3600);

       response.addCookie(c);

(2)从客户端请求中获取Cookie

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

       Cookie[] cs = request.getCookies();

       if(cs != null) {

           for(Cookie c : cs) {

              String name = URLDecoder.decode(c.getName(), "UTF-8");

              String value = URLDecoder.decode(c.getValue(), "UTF-8");

              String s = name + ": " + value + "<br/>";

              response.getWriter().print(s);

           }

       }

3. session
3.1 session概述

        HttpSession是javax.servlet.http包下的一个接口,用来进行会话跟踪。HttpSession对象是Servlet的三大域对象之一,其他两个域对象是HttpServletRequest和ServletContext。这三个域中,request的域范围最小,它的域范围是整个请求链,并且只在请求转发和包含时存在;session域对象的域范围是一次会话,而在一次会话中会产生多次请求,因此session的域范围要比request大;application的域范围是最大的,因为一个web应用只有唯一的一个application对象,只有当web应用被移出服务器或服务器关闭它才死亡,它的域范围是整个应用。

3.2 session常用方法

    (1)voidsetAttribute(String name,Object value):向域中添加域属性;

    (2)ObjectgetAttribute(String name):从域中获取指定名称的属性值;

    (3)VoidremoveAttribute(String name):移出域中指定名称的域属性

Session相关方法:

    (a)String getId():获取sessionId;

    (b)intgetMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;

    (c)voidsetMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;

    (d)long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;

    (e)longgetLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;

    (f)voidinvalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;

    (g)booleanisNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。

3.3 session对象的获取

        如果请求时,cookie中有jsessionid这个cookie,那么request.getSession()就会根据jsessionid值查找session的id,如果查找到,会使用已有的,如果没有查找到,会创建。

        如果请求时,cookie中没有jsessionid这个cookie,那么request.getSession()就会创建一个新的session对象.

3.4 session实现原理

         session底层是依赖Cookie,当首次使用session时,服务器端要创建session,session是保存在服务器端,而给客户端的session的id(一个cookie中保存了sessionId)。客户端带走的是sessionId,而数据是保存在session中。

        当客户端再次访问服务器时,在请求中会带上sessionId,而服务器会通过sessionId找到对应的session,而无需再创建新的session。


3.5 session对象的销毁分析

浏览器关闭了,session对象不会销毁的,session的销毁与关闭浏览器无关.

session对象销毁方式:

         (1)关闭服务器         

         (2)默认超时              

                  在tomcat/conf/web.xml文件中设置了session默认超时时间

                     <session-config>

                                   <session-timeout>30</session-timeout>

                          </session-config>                   

                  默认30分钟超时         

         (3)可以设置session超时时间(以秒为单位)

                   void setMaxInactiveInterval(int interval) 

         (4)销毁session

                  invalidate();

3.6 session失效

     session失效有如下几个原因:

        (1)客户端的请求中没有sessionId。可能是因为这是第一次请求(开始一个新的会话),也可能是服务器设置Cookie的maxAge为0导致的;

        (2)客户端请求中存在sessionId,但这个sessionId在session池中没有匹配的session对象。这可能是因为session太久没有使用,服务器把session从池中移除的原因;

        (3)客户端请求中存在sessionId,但匹配的session对象被标记为失效!这可能是因为服务器调用了session.invalidate()方法导致的。

4. URL重写
4.1 URL重写概述

        如果浏览器不支持Cookie或用户阻止了所有Cookie,可以把会话ID附加在HTML页面中所有的URL上,这些页面作为响应发送给客户。这样,当用户单击URL时,会话ID被自动作为请求头的一部分而不是作为头行发送回服务器。这种方法称为URL重写(URL rewriting)。

4.2 URL重写的作用

        当客户机不接受cookie时,server就使用URL重写作为会话跟踪的基本方式,URL重写,添加了附加数据(会话ID)到请求的URL路径上。 会话ID必须被编码作为该URL字符串中的路径参数。该参数的名称为jsessionid,简单说就是cookie禁用了jsessionid就不能携带,那么每次请求,都是一个新的session对象。如果想要使用同一个session对象,可以使用url重写.

         response.encodeRedirectURL(java.lang.String url)

                  用于对sendRedirect方法后的url地址进行重写。

         response.encodeURL(java.lang.String url)

                  用于对表单action和超链接的url地址进行重写
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值