6.Cookie和Session

 1  /*会话*/ (开一个浏览器,访问几个web资源,然后关闭浏览器,这个过程为一个对话)
 2   /*保存*/会话数据的两种技术(cookie  session)
 3       1.Cookie (客户端技术)(数据保存在客户端中)
 4              程序把每个用户的数据以cookie的形式写给用户各自的浏览器,当用户使用浏览器再去访问服务中的web资源时,就会带着各自的数据去,这样web资源处理的就是用户各自的数据了
 5          
 6          2.session(服务器端技术(数据保存在服务器中)    
 7              服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其实web资源再从用户各自的session中取出数据为用户服务
 8              
 9  /*cookie案例,显示用户上次访问网站的时间*/  
//删除一个 cookie  设置maxAge为0
public class CookieDemo2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        Cookie cookie = new Cookie("lastAcceptTime",System.currentTimeMillis()+"");
        cookie.setMaxAge(0);
        cookie.setPath("/day07");
        response.addCookie(cookie);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
//显示用户上次访问网站的时间
public class CookieDemo1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter pw = response.getWriter();
        //pw.print("<a href = '/day07/servlet/CookieDemo2'>请求上次访问时间</a>");
        pw.print("上次访问的时间为:");
        
        //获得用户的时间cookie
        Cookie cookies[] = request.getCookies();
        for(int i=0; cookies!=null && i<cookies.length;i++) {           //注意:这里的判断顺序不能写反,不然会有异常 (先判断是否为空,再去使用)
            if (cookies[i].getName().equals("lastAcceptTime")) {        //而且,不能这样判断    cookies[i]!=null (这样判断也是相当于先使用 后判断  ,不行)
                long cookieValue = Long.parseLong(cookies[i].getValue());  //得到用户上次访问的时间
                Date date = new Date(cookieValue);
                pw.print(date.toLocaleString());
                
            }
        }
        
        //给用户回送当前最新的访问时间
        Cookie cookie = new Cookie("lastAcceptTime",System.currentTimeMillis()+"");
        cookie.setMaxAge(1*24*3600);
        cookie.setPath("/day07");
        response.addCookie(cookie);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}10  11  /*Cookie细节*/12  1.一个cookie只能标识一种信息,它至少含有一个标识该信息的名称(name)和设置值(value)13  2.一个web站点可以给一个web浏览器发送多个Cookie,一个web浏览器也可以存储多个web站点提供的cookie14  3.浏览器一般只允它是一个会话级别的cookie(即存储在浏览器的内存中) 用户退出浏览器之后即被删除15          允许存放300个cookie,每个站点最多存放20个cookie,每个cookie大小限制为4KB  (为了性能考虑)16          若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge并给出一个以秒为单位的时间,将这个时间设为0 则是命令该浏览器删除该cook17  4.如果创建了一个cookie,并将它发送到浏览器,默认情况下,18  5.注意:删除cookie时(过程:创建一个新cookie(与删除的一样),设置maxAge为0,设置path,(即该cookie除了maxAge不一样,其他全一样)发送给浏览器),path必须保持一致,否则不会删除    /*CookieDemo2*/
                       
/*session对象*/
(生命周期:出生(第一次碰到getSession) 摧毁(关浏览器也不会死,session在服务器中,30分钟后无人使用后摧毁)) 服务器是如何实现一个session为一个浏览器服务的?
session 实现原理:(其实 /*session工作基于cookie*/  1.每个session创建的时候都有一个ID号,而这个ID号 以cookie的形式回写给浏览器,
  2.浏览器下次来访问服务器,就会带着ID号过来,服务器就取出指定session为浏览器服务
(注意:这里回写的cookie是 /*没有设置有效期的*/,浏览器关了,cookie就没有了,下次访问,浏览器就不能用指定的session,服务器会创建一个新的session为浏览器服务)
   (解决这个问题:创建session的时候,重新写一个cookie,并设置有效期,覆盖原来的,
session的一些小细节:
    1.如果用户把cookie给禁了,服务器给浏览器回送cookie的时候,浏览器就不要这个cookie了,就不能找到指定的session拿到数据,而是创建一个新的session(对127.0.0.1不阻止)
  
  (解决办法:将sessionId重写到到URL中 )      
  (getSession方法执行过程,先看下有没有以cookie的方式带ID来,再看下有没有以超链接的方式带ID来),如果两个都没带过来,就创建新的session,否则,根据指定ID找到指定session)35                                                        
             
       2.如果没有禁cookie,同时将url重写了的时候,当服务器一旦发现浏览器可以接收cookie的时候,就不会执行重写的那个方法 encodeURL
                                            
       3.通过url重写的方法,在浏览器关闭之后,并不能保存上次购买的东西,如 cookie没有设置有效期的时候出现的情况 (这个问题无法解决)
                                            
       4.在一个浏览器中,有多个选项卡(多个窗口) ,因为是基于一个浏览器,所以用到的是同一个session . 
                                            
       
   
使用session完成用户登录 1.在servlet1(登录)中,通过HTML中的表单,拿到 账号和 密码,然后进行判断 ,如果账号密码都符合,就向session中存储一个登录标记
    request.getSession().setAttribute("user", username); 存储标记完成后,重定向到指定jsp,提示该用户成功登录 。 如果,账号密码不符合 ,打印相关提示信息 2.在servlet2(注销)中,通过 session.removeAttribute("user"); ,删除标记,即可完成注销,然后跳到指定jsp,提示相关信息 3.jsp中 有登录 和注销 超链接 可以完成登录 注销操作(jsp中 可以根据标记 拿到账户信息)
客户端防表单重复提交和服务器端session防表单重复提交 客户端防表单重复提交 (用JavaScript)(两种方式:1.提交一次后,后面的提交无效;2.点击一次提交按钮后,提交按钮失效) 服务器端session防表单重复提交:(一个servlet 产生表单(表单通过jsp产生(创建的之后需要隐藏存储在session中的随机数)))
       
1.表单通过程序打给浏览器,这个程序在给浏览器打印表单的时候,在每一个表单里面都带上一个随机数(唯一的ID号),并且这个随机数在服务器中,也会存储一份 2.浏览器收到这个表单,点击提交的时候,就会带着这个随机数过来 3.在服务器端,检测带过来的随机数在服务器端有没有,如果有的话,意味着这个随机数没有提交过,就让其顺利提交; 提交之后,马上把这个随机数从服务器中删除,下次浏览器再提交过来,带过来的随机数在服务器中并不存在,所以服务器就不让其提交 session实现验证码的校验 (三个文件) 1.一个jsp文件用于在浏览器显示表单,(用户名,密码,验证码(通过servlet1获取)) 2.servlet1用于随机验证码的生成(除了给jsp,也要存储一份在session中) 3.servlet2用于检验验证码是否正确(拿到在session中的验证码 和 表单中用户敲的验证码) (注意字符编码问题) /*三个域对象的总结*/ 何时用何种容器(request,ServletContext,session)    request域:数据显示完了就没用了,就采用request域作为容器 (请求结束,数据消失)   session域:数据显示完了,等一会还要使用 (如随机验证码,显示完了,还要用于检测)   ServletContext域:数据显示给用户看了之后,不仅等一会要用的,而且还要给别人用 (聊天室)

原文地址:https://www.cnblogs.com/xuzekun/p/7358227.html