您的位置:首页 > 编程语言 > Java开发

Javaweb之cookie和session

2016-09-14 17:08 405 查看
一、会话的概念

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

  有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,这称之为有状态会话。

二、会话过程中要解决的一些问题

  每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。

三、保存会话数据的两种技术

3.1、Cookie机制

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

3.2、Session机制

  session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。

  当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识-称为session id,如果已经包含一个sessionid则说明以前已经为这个客户创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数)。

如果客户请求不包含session id,则服务器会为这个客户创建一个session并且生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存。

3.3、Cookie机制和Session机制的区别

1、从存取方式上比较
Cookie中只能保存ASCII字符串,如果需要存取Unicode字符或者二进制数据,需要进行UTF-8,GBK或者BASE64等方式的编码。Cookie中也不能直接存取Java对象。若要存储稍微复杂的信息,使用Cookie是比较困难的。
而Session中可以存取任何类型的数据,包括而不限于String、Integer、List、Map等。Session中也可以直接保存Java Bean乃至任何Java类,对象等,使用起来非常方便。可以把Session看做是一个Java容器类。
2、从隐私安全上比较
Cookie存储在客户端浏览器中,对客户端是可见的,客户端的一些程序可能会窥探、复制甚至修改Cookie中的内容。而Session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的危险。
如果选用Cookie,比较好的办法是,敏感的信息如账号密码等尽量不要写到Cookie中。最好是像Google、Baidu那样将Cookie信息加密,提交到服务器后再进行解密,保证Cookie中的信息只有自己能读得懂。而如果选择Session就省事多了,反正是放在服务器上,Session里任何隐私都可以。
3、从有效期上比较
Cookie能实现信息永久的保存,只需要设置Cookie的maxAge属性为一个很大很大的数字或者Integer.MAX_VALUE就可以了。如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。

如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。

存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。
使用Session理论上也能实现这种效果。只要调用方法setMaxInactiveInterval(Integer. MAX_VALUE)不就可以了么。但是由于Session依赖于名为JSESSIONID的Cookie,而Cookie JSESSIONID的maxAge默认为-1,只要关闭了浏览器该Session就会失效,因此Session不能实现信息永久有效的效果。使用URL地址重写也不能实现。
而且如果设置Session的超时时间过长,服务器累计的Session就会越多,越容易导致内存溢出。
4、从对服务器的负担上比较
Session是保存在服务器端的,每个用户都会产生一个Session。如果并发访问的用户非常多,会产生非常多的Session,消耗大量的内存。因此像Google、Baidu、Sina这样并发访问量极高的网站,是不太可能使用Session来追踪客户会话的。
而Cookie保存在客户端,不占用服务器资源。如果并发浏览的用户非常多,Cookie是很好的选择。对于Google、Baidu、Sina来说,Cookie也许是唯一的选择。
5、从浏览器支持上比较
Cookie是需要客户端浏览器支持的。如果客户端禁用了Cookie,或者不支持Cookie,则会话跟踪会失效。对于WAP上的应用,常规的Cookie就派不上用场了。
如果客户端浏览器不支持Cookie,需要使用Session以及URL地址重写。需要注意的是所有的用到Session程序的URL都要使用response.encodeURL(String URL)或者response.encodeRedirectURL(String URL)进行URL地址重写,否则导致Session会话跟踪失败。对于WAP应用来说,Session+URL地址重写也许是它唯一的选择。
如果客户端支持Cookie,则Cookie既可以设为本浏览器窗口以及子窗口内有效(把maxAge设为-1),也可以设为所有浏览器窗口内有效(把maxAge设为某个大于0的整数)。但Session只能在本浏览器窗口以及其子窗口内有效。如果两个浏览器窗口互不相干,它们将使用两个不同的Session。
6、从跨域名上比较
Cookie支持跨域名访问,例如将domain属性设置为".helloweenvsfei.com",则以".h
1da70
elloweenvsfei.com"为后缀的所有域名均可以访问该Cookie。跨域名Cookie现在被广泛用在网络中,例如Google、Baidu、Sina等。而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。

四、Cookie使用范例

4.1、使用cookie记录用户上一次访问的时间

[java] view
plain copy

 





package com.servlet.study;  

   

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;  

/** 

 * cookie实例:获取用户上一次访问的时间 

 */  

public classCookieDemo1 extends HttpServlet {  

   

   publicvoiddoGet(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();  

        //获取浏览器访问访问服务器时传递过来的cookie数组  

        Cookie[] cookies =request.getCookies();  

        //如果用户是第一次访问,那么得到的cookies将是null  

        if (cookies!=null) {  

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

            for (int i = 0; i < cookies.length; i++) {  

                Cookie cookie = cookies[i];  

                if (cookie.getName().equals("lastAccessTime")){  

                    Long lastAccessTime =Long.parseLong(cookie.getValue());  

                    Date date = new Date(lastAccessTime);  

                    out.write(date.toLocaleString());  

                }  

            }  

        }else {  

            out.write("这是您第一次访问本站!");  

        }  

         

        //用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器  

        Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime  

        //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器  

        response.addCookie(cookie);  

   }  

   publicvoiddoPost(HttpServletRequest request, HttpServletResponse response)  

            throws ServletException, IOException {  

        doGet(request, response);  

   }  

}  

第一次访问时这个Servlet时会提示这是您第一次访问本网站,点击浏览器的刷新按钮,进行第二次访问,此时就服务器就可以通过cookie获取浏览器上一次访问的时间了。

   在上面的例子中,在程序代码中并没有使用setMaxAge方法设置cookie的有效期,所以当关闭浏览器之后,cookie就失效了,要想在关闭了浏览器之后,cookie依然有效,那么在创建cookie时,就要为cookie设置一个有效期。如下所示:

//用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器

Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime

 //设置Cookie的有效期为1天

 cookie.setMaxAge(24*60*60);

 //将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器

 response.addCookie(cookie);

  用户第一次访问时,服务器发送给浏览器的cookie就存储到了硬盘上,这样即使关闭了浏览器,下次再访问时,也依然可以通过cookie获取用户上一次访问的时间。

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

 5.2、cookie中存取中文

要想在cookie中存储中文,那么必须使用URLEncoder类里面的encode(String s, String enc)方法进行中文转码,例如:

Cookie cookie = newCookie("userName", URLEncoder.encode("Cookie测试","UTF-8"));

response.addCookie(cookie);

在获取cookie中的中文数据时,再使用URLDecoder类里面的decode(String s, String enc)进行解码,例如:

URLDecoder.decode(cookies[i].getValue(),"UTF-8")

六、session使用范例

6.1、服务器是如何实现一个session为一个用户浏览器服务的?

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

[java] view
plain copy

 





package com.servlet.study;  

   

import java.io.IOException;  

import javax.servlet.ServletException;  

import javax.servlet.http.HttpServlet;  

import javax.servlet.http.HttpServletRequest;  

import javax.servlet.http.HttpServletResponse;  

import javax.servlet.http.HttpSession;  

   

public classSessionDemo1 extends HttpServlet {  

   

   publicvoiddoGet(HttpServletRequest request, HttpServletResponse response)  

            throws ServletException, IOException {  

   

        response.setCharacterEncoding("UTF=8");  

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

        //使用request对象的getSession()获取session,如果session不存在则创建一个  

        HttpSession session = request.getSession();  

        //将数据存储到session中  

        session.setAttribute("data","Session测试");  

        //获取session的Id  

        String sessionId = session.getId();  

        //判断session是不是新创建的  

        if (session.isNew()) {  

            response.getWriter().print("session创建成功,session的id是:"+sessionId);  

        }else {  

            response.getWriter().print("服务器已经存在该session了,session的id是:"+sessionId);  

        }  

   }  

   

   publicvoiddoPost(HttpServletRequest request, HttpServletResponse response)  

            throws ServletException, IOException {  

        doGet(request, response);  

   }  

}  

第一次访问时,服务器会创建一个新的sesion,并且把session的Id以cookie的形式发送给客户端浏览器,点击刷新按钮,再次请求服务器,此时就可以看到浏览器再请求服务器时,会把存储到cookie中的session的Id一起传递到服务器端了

6.2、session对象的销毁时机

  session对象默认30分钟没有使用,则服务器会自动销毁session,在web.xml文件中可以手工配置session的失效时间,例如:

[html] view
plain copy

 





<?xmlversionxmlversion="1.0" encoding="UTF-8"?>  

<web-appversionweb-appversion="2.5"  

   xmlns="http://java.sun.com/xml/ns/javaee"  

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  

    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  

  <display-name></display-name>  

  <welcome-file-list>  

   <welcome-file>index.jsp</welcome-file>  

  </welcome-file-list>  

  <!-- 设置Session的有效时间:以分钟为单位-->  

    <session-config>  

        <session-timeout>15</session-timeout>  

    </session-config>  

</web-app>  

当需要在程序中手动设置Session失效时,可以手工调用session.invalidate方法,摧毁session。

[java] view
plain copy

 





HttpSession session = request.getSession();  

//手工调用session.invalidate方法,摧毁session  

session.invalidate();  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javaweb java cookie session