zoukankan      html  css  js  c++  java
  • 17、Cookie和HttpSeesion

    一、会话概述

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

    会话能保持各个客户端自己的数据

    保存会话数据的两种技术:Cookie、HttpSession

    二、Cookie

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

    1、 Cookie 方法

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

    2、Cookie 细节

    (1)一个Cookie只能标识一种信息(String),它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)
    (2)一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
    (3)创建一个 cookie,cookie 是 servlet 发送到 Web 浏览器的少量信息,这些信息由浏览器保存,然后发送回服务器。cookie 的值可以唯一地标识客户端,因此 cookie 常用于会话管理。
    (4)一个 cookie 拥有一个名称、一个值和一些可选属性,比如注释、路径和域限定符、最大生存时间和版本号。一些 Web 浏览器在处理可选属性方面存在 bug,因此有节制地使用这些属性可提高 servlet 的互操作性。
    (5)servlet 通过使用 HttpServletResponse#addCookie 方法将 cookie 发送到浏览器,该方法将字段添加到 HTTP 响应头,以便一次一个地将 cookie 发送到浏览器。浏览器应该支持每台 Web 服务器有 20 个 cookie,总共有 300 个 cookie,并且可能将每个 cookie 的大小限定为 4 KB。
    (6)浏览器通过向 HTTP 请求头添加字段将 cookie 返回给 servlet。服务器可使用 HttpServletRequest#getCookies 方法从请求中获取 cookie。一些 cookie 可能有相同的名称,但却有不同的路径属性。
    (7)如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
    注意,删除cookie时,path必须一致,否则不会删除
     

    3、属性

    name: 名称不能唯一确定一个cookie。路径可能不同
    value: 不能存中文
    path: 默认是写入cookie那个应用的访问路径
    如: http://localhost:8080/day10/servlet/cookieDemo1
    Path: / day10/servlet/
    当客户端访问服务器其它资源时,根据访问路径来决定是否带着cookie到服务器,当访问的路径是以cookie中path开头的路径,就带cookie,否则就不带
    maxAge: cookie的保存时间。默认是-1(表示保存在浏览器的内存中)
    负数:cookie存在浏览器的内存中。
    0:删除。路径要保持一致,否则会删错了。
    正数:缓存(持久化到磁盘中)的时间。
    1 Cookie cookie = new Cookie();  // 创建
    2 resquest.getCookies();  // 从浏览器获取Cookies
    3 response.addCookie();  // 写回浏览器
     1 // 保存客户端的最后访问时间
     2 public void doGet(HttpServletRequest request, HttpServletResponse response)
     3         throws ServletException, IOException {
     4     
     5     response.setContentType("text/html;charset=UTF-8");
     6     
     7     PrintWriter out = response.getWriter();
     8     
     9     // 保存客户端的最后访问时间
    10     Cookie[] cookies = request.getCookies();  // 获取所有Cookie
    11     for (int i = 0; cookies!=null&&i < cookies.length; i++) {  
    12         if("lastAccessTime".equals(cookies[i].getName())) {  // 判断当前Cookie的name是否想要的Cookie
    13             long l = Long.parseLong(cookies[i].getValue());  // 是想要的Cookie则取出value
    14             out.write("最后的访问时间:"+new Date(l).toLocaleString());
    15         }
    16     }
    17     
    18     // 创建Cookie
    19     Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");  // lastAccessTime为当前系统时间
    20     
    21     // 设置保存的时间
    22     cookie.setMaxAge(60*5);
    23     // 设置路径,其下应用都可以相互访问cookie
    24     cookie.setPath(request.getContextPath());  // 效果和setPath("/")一样,都是当前在服务器上的应用的根路径,/Cookie
    25 //        cookie.setPath("/");
    26     
    27     // 把Cookie信息写回客户端
    28     response.addCookie(cookie);
    29 }
     1 // 删除Cookie,覆盖相当于删除
     2 public void doGet(HttpServletRequest request, HttpServletResponse response)
     3         throws ServletException, IOException {
     4     // 创建Cookie
     5     Cookie cookie = new Cookie("lastAccessTime", "");  
     6             
     7     cookie.setPath(request.getContextPath());  // 设置Cookie的路径,否则可能删错
     8     // 设置保存的时间
     9     cookie.setMaxAge(0);  // 相当于删除
    10     
    11     response.addCookie(cookie);  // 将cookie写回缓存
    12 }
    out.print("<a href='"+request.getContextPath()+"/servlet/clear'>clear</a>");  // clear跳转到clear Servlet
     1 // 记住用户名
     2 public class LoginServlet extends HttpServlet {
     3 
     4     public void doGet(HttpServletRequest request, HttpServletResponse response)
     5             throws ServletException, IOException {
     6         
     7         response.setContentType("text/html;charset=UTF-8");
     8         PrintWriter out = response.getWriter();
     9         String userName = "";  // 第一次为空
    10         String checked = "";
    11         
    12         // 得到客户端保存的数据
    13         Cookie[] cookies = request.getCookies();
    14         for (int i = 0; cookies!=null && i < cookies.length; i++) {
    15             if("userName".equals(cookies[i].getName())) {
    16                 userName = cookies[i].getValue();
    17                 checked = "checked='checked'";
    18             }
    19         }
    20         
    21         // 绘制表单并提交表单
    22         out.write("<form action='"+request.getContextPath()+"/servlet/dologin' method='post'>");
    23         out.write("用户名 :<input type='text' name='userName' value='"+userName+"'/><br/>");
    24         out.write("密码 :<input type='password' name='pwd' /><br/>");
    25         out.write("<input type='checkbox' name='remember' "+checked+"/>记住用户名<br/>");
    26         out.write("<input type='submit'  value='登录'/><br/>");
    27         out.write("</form>");
    28     }
    29 }
     1 // 记住用户名登录操作
     2 public class DoLogin extends HttpServlet {
     3 
     4     public void doGet(HttpServletRequest request, HttpServletResponse response)
     5             throws ServletException, IOException {
     6         
     7         // 设置编解码方式
     8         request.setCharacterEncoding("UTF-8");
     9         response.setContentType("text/html;charset=UTF-8");
    10         
    11         PrintWriter out = response.getWriter();  // 输出流,和OutputStream一样,但是可以接受不同的类型数据写出
    12         
    13         // 获取表单数据
    14         String userName = request.getParameter("userName");
    15         String pwd = request.getParameter("pwd");
    16         String remember = request.getParameter("remember");
    17         
    18         Cookie cookie = new Cookie("userName", userName);
    19         cookie.setPath("/");  // 设置在当前应用下
    20         // 处理业务逻辑
    21         // 分发转向
    22         if("tom".equals(userName) && "123".equals(pwd)) {
    23             if(remember!=null) {  // 勾选记住密码,没勾选就是null
    24                 cookie.setMaxAge(Integer.MAX_VALUE);  // 永久保存
    25             } else {
    26                 cookie.setMaxAge(0);  // 不勾选删除Cookie
    27             }
    28             response.addCookie(cookie);  // 将Cookie写回到客户端
    29             out.write("登录成功");  // 输出到页面
    30         } else {
    31             out.write("登录失败");
    32             // 登录失败后2s重新登录
    33             response.setHeader("refresh", "2,url="+request.getContextPath()+"/servlet/login"); 
    34         }
    35     }
    36 }

    三、HttpSession

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

    1、Session和Cookie的主要区别

    (1)Cookie是把用户的数据写给用户的浏览器。
    (2)Session技术把用户的数据写到用户独占的session中。
    (3)Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。
     
     
    它也是一个域对象: session servletContext request
    同一个会话下 ,可以使一个应用的 多个资源共享数据
    cookie客户端技术,只能存字符串,不存密码等敏感信息 。HttpSession 服务器端的技术,它可以存对象,可以存密码,通过id区分不同用户 。
     
    request < session < servletContext
    request:一次请求有效,service之前创建,结束之后销毁
    session:一次会话有效,第一次访问服务器资源创建,会话结束销毁,当前应用的的多个servlet可以共享
    servlet:整个应用有效,多个用户可以访问
     
     

    2、常用方法

    把数据保存在HttpSession对象中,该对象也是一个域对象。
    1 void setAttribute(String name,Object value);
    2 Object getAttribute(String name);
    3 void removeAttribute(String name);
    4 HttpSession.getId():
    5 setMaxInactiveInterval(int interval)   // 设置session的存活时间,默认30分钟
    6 invalidate()  // 使此会话无效,退出登录

    3、getSession()内部执行原理(常用)

    HttpSession session = request.getSession();
    1、获取名称为JSESSIONID的cookie的值。
    2、没有这样的cookie,创建一个新的HttpSession对象,分配一个唯一的SessionID,并且向客户端写了一个名字为JSESSIONID=sessionID的cookie
    3、有这样的Cookie,获取cookie的值(即HttpSession对象的值),从服务器的内存中根据ID找那个HttpSession对象:
    找到了:取出继续为你服务。
    找不到:从2开始。(超过30min)
     
    HttpSession request.getSession(boolean create);
    参数:
    true:和getSession()功能一样。
    false:根据客户端JSESSIONID的cookie的值,找对应的HttpSession对象,找不到返回null(不会创建新的,只是查询)。
     
    session四种死法:
    1、过了默认时间
    2、强制销毁
    3、设置最大存活时间
    4、在web.xml中设置

     4、客户端禁用Cookie后的会话数据保存问题

    客户端禁用cookie:浏览器永远不会向服务器发送cookie的请求消息头
     
    解决方案:
    方案一:在主页上给出提示:请不要禁用您的cookie
    方案二:URL重写。必须对网站的所有地址都重写。
     
    http://url--->http://url;JSESSIONID=111
    response.encodeURL(String url);
    看浏览器有没有发送cookie请求消息头,没有就重写URL,有就不重写。
    request.getSession();必须写
     
     
     
     
     
     
     
    有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
  • 相关阅读:
    C#实现任意源组播与特定源组播
    张灵甫此人性格偏激,赌性重,喜欢冒险,做事不留后路,更适合担任中下层军官(要自己掌控着自己的命运)
    Delphi 中 断言 Assert 用法
    桌面程序阻止Windows关机(使用Message.Result取得DefWindowProc API函数的返回值,非常重要)
    Asp.net vnext的IIS部署
    Asp.net vNext 学习3
    EasyUI的后台界面
    C#框架
    前端分离规范
    AngularJS html5Mode与ASP.NET MVC路由
  • 原文地址:https://www.cnblogs.com/1989guojie/p/6139734.html
Copyright © 2011-2022 走看看