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域:数据显示给用户看了之后,不仅等一会要用的,而且还要给别人用 (聊天室)