zoukankan      html  css  js  c++  java
  • Cookie 和 Session

      在Web应用中,一个客户端(浏览器)与Web服务器之间连续发生的一系列请求和响应的过程称为一个会话(如一个用户在某购物网站上的整个购物过程就是一个会话)。在整个会话过程中,客户端与服务器端的交互会产生一些数据,而Web服务器需要对这些数据进行保存。在Servlet技术中,主要提供两个用于保存会话数据的对象,分别是Cookie和Session。

    1 Cookie 对象                                                                                        

      Cookied主要用于将会话保存到用户的浏览器中,从而使浏览器和服务器可以更好地进行数据交互

      Cookie是浏览器端使用的一种记录用户状态的机制,它实际上是一小段保存在浏览器中的文本信息。当客户端通过浏览器请求服务器时,如果服务器需要记录该用户的状态,就会使用response对象向客户端浏览器颁发一个Cookie,客户端浏览器会把Cookie保存起来。当通过浏览器再次请求该网站时,浏览器会把请求的网址连同该Cookie一同提交给服务器,服务器会检查该Cookie,以此辨认用户状态。

      服务器向客户端发送Cookie时,会在HTTP响应头字段中增加Set-Cookie响应头字段。语法格式:

    Set-Cookie: user=admin; path=/;
    
    user:表示Cookie名称;
    admin: 表示Cookie的值;
    Path:表示Cookie的属性

    Cookie在浏览器和服务器之间的传输过程如下图:

      当用户第一次通过浏览器访问服务器时,服务器会在响应消息中加入Set-Cookie头字段,将用户信息以Cookie的形式发给浏览器。用户浏览器接收了服务器发送的Cookie信息,就会将它保存在浏览器的缓冲区中,这样,当浏览器后续访问该服务器时,会在请求消息中将用户信息以Cookie的形式发送给Web浏览器,从而使服务器端分标出当前请求是由哪个用户发出的。

    1.1 Cookie API

      Java中的javax.servlet.http.Cookie类用于创建一个Cookie

    Cookie类的主要方法

    No.

    方法

    类型

    描述

    1

    Cookie(String name, String value)

    构造方法

    实例化Cookie对象,传入Cookie名称和Cookie的值

    2

    public String getName()

    普通方法

    用于返回Cookie的名字

    3

    public String getValue()

    普通方法

    用于返回Cookie的值

    4

    public void setValue(String newValue)

    普通方法

    用于为Cookie设置一个新的值

    5

    public void setMaxAge(int expiry)

    普通方法

    用于设置Cookie子浏览器客户机上保持有效的秒数。即Cookie的有效期,当服务器给浏览器回送一个Cookie时,如果在服务器端没有调用setMaxAge方法设置Cookie的有效期,那么Cookie的有效期只在一次会话过程中有效,用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一次会话,当用户关闭浏览器,会话就结束了,此时Cookie就会失效,如果在服务器端使用setMaxAge方法设置了Cookie的有效期,比如设置了30分钟,那么当服务器把cookie发送给浏览器时,此时Cookie就会在客户端的硬盘上存储30分钟,在30分钟内,即使浏览器关了,Cookie依然存在,在30分钟内,打开浏览器访问服务器时,浏览器都会把Cookie一起带上,这样就可以在服务器端获取到客户端浏览器传递过来的Cookie里面的信息了,这就是Cookie设置maxAge和不设置maxAge的区别,不设置maxAge,那么Cookie就只在一次会话中有效,一旦用户关闭了浏览器,那么Cookie就没有了,那么浏览器是怎么做到这一点的呢,我们启动一个浏览器,就相当于启动一个应用程序,而服务器回送的Cookie首先是存在浏览器的缓存中的,当浏览器关闭时,浏览器的缓存自然就没有了,所以存储在缓存中的Cookie自然就被清掉了,而如果设置了Cookie的有效期,那么浏览器在关闭时,就会把缓存中的cookie写到硬盘上存储起来,这样Cookie就能够一直存在了。

    6

    public int getMaxAge()

    普通方法

    用于返回Cookie子浏览器客户机上保持有效的秒数

    7

    public void setPath(String uri)

    普通方法

    设置Cookie的有效路径,比如把Cookie的有效路径设置为"/xdp",那么浏览器访问"xdp"目录下的web资源时,都会带上Cookie,再比如把cookie的有效路径设置为"/xdp/gacl",那么浏览器只有在访问"xdp"目录下的"gacl"这个目录里面的web资源时才会带上Cookie一起访问,而当访问"xdp"目录下的web资源时,浏览器是不带cookie的

    8

    public String getPath()

    普通方法

    获取Cookie的有效路径

    9

    public void setDomain(String pattern)

    普通方法

     设置Cookie的有效域

    10

    public String getDomain()

    普通方法

     获取Cookie的有效域

    1.2  示例: 显示用户上次访问的时间

     1 package cn.cookie;
     2 import java.io.IOException;
     3 import java.text.SimpleDateFormat;
     4 import java.util.Date;
     5 import javax.servlet.ServletException;
     6 import javax.servlet.http.Cookie;
     7 import javax.servlet.http.HttpServlet;
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 
    11 public class cookie1 extends HttpServlet {
    12     private static final long serialVersionUID = 1L;
    13     public void doGet(HttpServletRequest request, HttpServletResponse response)
    14             throws ServletException, IOException {
    15         //设置服务器端以UTF-8编码进行输出
    16         response.setCharacterEncoding("UTF-8");
    17         //设置浏览器以UTF-8编码进行接收,解决中文乱码问题
    18         response.setContentType("text/html; charset=UTF-8");
    19         String lastAccessTime=null;
    20         Cookie[] cookies = request.getCookies();
    21         for(int i=0; cookies!=null && i<cookies.length; i++){
    22             if("lastAccess".equals(cookies[i].getName())){
    23                 lastAccessTime = cookies[i].getValue();
    24                 break;
    25             }
    26         }    
    27         if(lastAccessTime == null){
    28             response.getWriter().print("您是首次访问本站");
    29         }else{
    30             response.getWriter().print("您上次访问的时间是:"+lastAccessTime);
    31         }
    32         //创建cookie,将当前时间作为cookie的值发送给客户端
    33         String currentTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
    34         Cookie cookie = new Cookie("lastAccess", currentTime);    
    35         response.addCookie(cookie);
    36     }    
    37     public void doPost(HttpServletRequest request, HttpServletResponse response)
    38             throws ServletException, IOException {
    39         
    40     }
    41 }

    第一次访问,运行结果:

    刷新后:

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

    在34行后添加如下代码

    //设置Cookie的有效期为1天
    cookie.setMaxAge(24*60*60);

    这样即使关闭了浏览器,下次再访问时,也依然可以通过cookie获取用户上一次访问的时间。

     1.3 Cookie注意细节

      (1)一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。

      (2)一个Web站点可以给有个Web浏览器发送多个Cookie,一个Web浏览器也可以存储多个Web站点提供的Cookie。

      (3)浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4kb。

      (4)如果创建了一个cookie,并将他发送给浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器中),用户推出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAges,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。

    1.4 Cookie中存取中文

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

    1 Cookie cookie = new Cookie("userName", URLEncoder.encode("您好,哈哈", "UTF-8"));
    2 response.addCookie(cookie);

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

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

    2 Session 对象                                                                                                       

      Session是服务器端使用的一种记录客户端状态的机制。当浏览器访问Web服务器时,Servlet容器就会创建一个Session对象和ID属性,当客户端后续访问服务器时,只要将标识(ID)号传递给服务器,服务器就能判断出该请求是哪个客户端发送的,从而选择与之响应的Session对象并为其服务。

    2.1 Session API

      由于Session是与每个请求消息紧密相关的,因此,在HTTPServletRequest中定义了用于获取Session对象的getSession方法,该方法两种重载形式:

    public HttpSession getSession(boolean create);
    public HttpSession getSession();
    
    //第一个getSession()方法根据传递的参数判断是否创建新的HttpSession对象,如果参数为true,则在相关的HttpSession对象不存在时返回新的HttpSession。否则不创建。
    //第二中方法getSession()相当于第一个方法参数为true的情况。

    注意:由于getCookie()方法可能会产生发送会话标号的Cookie头字段,因此必须在发送任何响应内容之前调用getSession()方法。

    HttpSession接口的常用方法:

    方法声明 功能描述
    Sting getId() 用于返回与当前HttpSession对象关联的会话标识号
    long getCreationTime() 返回Session创建的时间。这个时间是创建Session的时间与1970年1月1日0时0分0秒之间时间差的毫秒标识形式
    long getLastAccessedTime() 返回客户端最后一次发送与Session相关请求的时间。如上
    void setMaxInactiveInterval(int interval) 用于设置当前HttpSession对象可空闲的以秒为单位最长的时间,也就是修改当前会话的默认超时间隔
    vboolea isNew() 判断当前HttpSession对象是否是新创建的
    void invalidate() 用于强制使Session对象无效
    ServletContext getServletContext() 用于返回当前HttpSession对象所书序的Web应用程序对象,即代表当前Web应用程序的ServletContext对象
    void setArribite(String name, Object value) 用于将一个对象与一个名称关联后存储到当前的HttpSession对象中
    String getArribute() 用于从当前HttpSession对象中返回指定名称的属性对象
    void removeAttribute(String name) 用于从当前HttpSession对象中删除指定名称属性

     2.2 Session保存用户信息过程

      由于客户端需要接收、记录和回送Session对象的ID,因此,在通常情况下,Session是借助Cookie技术传递ID属性的。以网站购物为例,以下为Session保存用户信息的原理。

      浏览器A和浏览器B都调用buyServlet将商品添加到购物车,然后调用payServlet进行商品结算。A和B购买过程类似。当浏览器A访问购物网站时,服务器为用户甲创建了一个Session对象(相当于购物车)。当浏览器A将vivo添加到购物车时,vivo的信息会存放到Session对象中,同时,服务器会将Session对象的ID属性以Cookie(Set-Cookie:JSESSION=111)的形式返回给浏览器。当浏览器A完成购物并进行结账时,需要想服务器发送结账请求,这时,浏览器将自动在请求消息头中将Cookie(Set-Cookie:JSESSION=111)信息发送给服务器,服务器会根据ID属性找到浏览器A所创建的Session对象,并将Session对象存放的vivo信息取出并进项结算。

     2.3 服务器实现一个session为一个用户浏览器服务

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

     1 package cn.cookie;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import javax.servlet.http.HttpSession;
     9 
    10 public class session1 extends HttpServlet {
    11     private static final long serialVersionUID = 1L;
    12     public void doGet(HttpServletRequest request, HttpServletResponse response)
    13             throws ServletException, IOException {
    14         response.setCharacterEncoding("UTF=8");
    15         response.setContentType("text/html;charset=UTF-8");
    16         //使用request对象的getSession()获取session,如果session不存在则创建一个
    17         HttpSession session = request.getSession();
    18         session.setAttribute("data", "没有耳朵的猫");
    19         String sessionId = session.getId();
    20         if(session.isNew()){
    21             response.getWriter().print("session创建成功,session的id是:"+sessionId);
    22         }else{
    23             response.getWriter().print("服务器已经存在该session了,session的id是:"+sessionId);
    24         }
    25         
    26     }
    27     
    28     public void doPost(HttpServletRequest request, HttpServletResponse response)
    29             throws ServletException, IOException {    
    30     }
    31 
    32 }

    第一次访问时,服务器会创建一个新的sesion,并且把session的Id以cookie的形式发送给客户端浏览器,如下图所示:

    点击刷新按钮,再次请求服务器,此时就可以看到浏览器再请求服务器时,会把存储到cookie中的session的Id一起传递到服务器端了,如下图所示:

     2018-10-08 11:42:24

  • 相关阅读:
    使用japidocs生成springboot api文档
    springboot通过javaconfig配置jackson
    SAP 合并请求
    windows server终端服务加密级别
    Microsoft Windows远程桌面协议服务程序密钥泄露漏洞(CVE-2005-1794)
    SAP RFC函数RFC_READ_TABLE使用与优化
    springboot maven项目引入并打包本地JAR
    springboot通过javaconfig实现logback配置
    File类以及文件简记
    解释性语言和编译型语言简记
  • 原文地址:https://www.cnblogs.com/qqiua/p/9751582.html
Copyright © 2011-2022 走看看