day11--cookie-session会话技术

  1. 会话技术概述
    在浏览器和服务器建立链接之后,浏览器和服务器为了完成某一功能,浏览器发送一次或多次请求,服务器作出的一次或多次响应,在浏览器关闭之前,所有的请求和响应就构成了一次会话。
    1. HTTP协议特点:
      HTTP无状态协议:当前请求和上一次请求之间没有任何的联系。

    2. 使用会话技术的原因:
      a. 为了能够在多次请求响应之间共享数据,所有提出会话技术。

    3. 会话技术–cookie
      a. cookie的实现原理
      服务器会在第一次响应的时候,通过set-cookie响应头,将需要使用的数据发送到浏览器,浏览器会自动将其作为cookie保存。在下一次请求时,会自动携带一个cookie请求头,其中包含的内容就是浏览器中的cookie信息。
      b. cookie特点:
      cookie技术是一门浏览器端的技术,数据保存在浏览器端。保存安全性要求较低的数据。而存储时间较长的数据。
      c. 案例:返回上次访问页面的时间:
      i. 在第一响应中,set-cookie保存的数据会到达浏览器。并且保留在浏览器中。
      ii. 在下一次的请求中,使用cookie请求头,获取cookie,得到结果。
      代码实现:
      package cn.tedu.cookie;

       	import java.io.IOException;
       	import java.util.Date;
       	
       	import javax.servlet.ServletException;
       	import javax.servlet.http.HttpServlet;
       	import javax.servlet.http.HttpServletRequest;
       	import javax.servlet.http.HttpServletResponse;
       	//cookie原理实现
       	public class CookieDemo1 extends HttpServlet {
       	
       	        public void doGet(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                //乱码解决
       	                response.setContentType("text/html;charset=utf-8");
       	                //返回页面上一次的访问时间
       	                Date date = new Date();
       	                String time = date.toLocaleString();//获取当前时间
       	                //1.设置set-cookie响应头
       	                response.setHeader("set-cookie", "time="+time);
       	                //2.获取请求头cookie
       	                String cookie = request.getHeader("cookie");
       	                //3.打印结果
       	                if(cookie == null){//初次请求没有cookie请求头,所以cookie请求头为null
       	                        
       	                        response.getWriter().write("您是初次访问本页面");
       	                }else{
       	                        
       	                        response.getWriter().write("上次访问页面的时间为:"+cookie);
       	                }
       	        }
       	
       	        public void doPost(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                doGet(request, response);
       	
       	        }
       	
       	}
      
    4. Cookie类
      Sun公司提供了一个Cookie类,可以通过创建对象的方式,来创建cookie。
      a. 创建cookie
      Cookie cookie = new Cookie(String name,String value);
      b. 设置cookie的生命时长
      cookie的生命时长可以设置也可以不设置。如果不设置则当前cookie的生命时长,则cookie为一个会话级别的cookie,关闭浏览器当前cookie就会销毁。如果设置生命时长,则达到对应时间之后,会有浏览器自动销毁。
      cookie.setMaxAge(秒);
      c. 设置有效路径
      如果不设置有效路径,则当前cookie的有效路径为资源名称部分,在这一部分中可以共享cookie。如果设置有效路径,且为整个web应用,那么在整个web应用的虚拟路径级别之下都可以获取到当前cookie
      cookie.setPath(request.getContextPath()+"/");
      d. 发送cookie
      response.addCookie(Cookie)
      e. 获取cookie
      request.getCookies(); —Cookie[]
      f. 删除cookie
      发送一个与要删除的cookie完全相同的cookie,并且设置它的生命时长为0,则这个cookie就可以被销毁。完全相同的cookie,需要保证name+path+domain三者完成一致。
      g. 获取cookie的名字
      cookie.getName()
      h. 获取cookie的值
      cookie.getValue()
      i. 案例:通过cookie实现,页面上次访问时间:
      package cn.tedu.cookie;

       import java.io.IOException;
       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 class CookieDemo2 extends HttpServlet {
       
               public void doGet(HttpServletRequest request, HttpServletResponse response)
                       throws ServletException, IOException {
                       //乱码处理
                       response.setContentType("text/html;charset=utf-8");
                       Date date = new Date();
                       String time = date.toLocaleString();
                       //1.创建cookie
                       Cookie cookie = new Cookie("time",time);
                       //2.发送cookie--通过response对象发送
                       response.addCookie(cookie);
                       //3.获取cookie
                       Cookie[] cs = request.getCookies();
                       //遍历数组
                       Cookie timeC = null;
                       if(cs !=null){//初次访问页面时,没有任何cookie,所以会产生空指针异常,应该排除这种情况
                               for(Cookie c:cs){
                                       if("time".equals(c.getName())){//从数组中获取名称为time的cookie
                                               timeC = c;//当前cookie对象范围过小,无法在外侧代码操作,可以赋值给更大范围的变量去使用。
                                       }
                                       
                               }
                       }
                       
                       //4.打印结果
                       if(timeC == null){
                               response.getWriter().write("您是初次访问本页面");
                               
                       }else{
                               response.getWriter().write("上次访问页面的时间为:"+timeC.getValue());
                               
                       }
               }
       
               public void doPost(HttpServletRequest request, HttpServletResponse response)
                       throws ServletException, IOException {
                       doGet(request, response);
       
               }
       
       }
      
    5. EasyMall功能实现—记住用户名
      a. 导入login.jsp页面
      i. 从课前资料中复制login页面内容。
      ii. 将html页面修改为jsp页面
      b. 修改_head.jsp
      登录

      c. 创建LoginServlet.java
      package com.easymall.servlet;

       import java.io.IOException;
       
       import javax.servlet.ServletException;
       import javax.servlet.http.Cookie;
       import javax.servlet.http.HttpServlet;
       import javax.servlet.http.HttpServletRequest;
       import javax.servlet.http.HttpServletResponse;
       //登录Servlet
       public class LoginServlet extends HttpServlet {
       
               public void doGet(HttpServletRequest request, HttpServletResponse response)
                       throws ServletException, IOException {
                       //0.乱码处理
                       request.setCharacterEncoding("utf-8");
                       response.setContentType("text/html;charset=utf-8");
                       //1.获取参数
                       String username = request.getParameter("username");
                       String password = request.getParameter("password");
                       //获取是否记住用户名选项
                       String remname = request.getParameter("remname");//"true"   null
                       //2.记住用户名--cookie
                       //remname为"true"则需要记住用户名,反之为null不需要记住用户名。
                       if("true".equals(remname)){
                               Cookie cookie = new Cookie("remname",URLEncoder.encode(username, "utf-8"));
                               cookie.setMaxAge(60*60*24*30);//30天记住用户名
                               cookie.setPath(request.getContextPath()+"/");
                               response.addCookie(cookie);
                       }else{
                               Cookie cookie = new Cookie("remname", "");
                               cookie.setMaxAge(0);
                               cookie.setPath(request.getContextPath()+"/");
                               response.addCookie(cookie);
                       }
                       //3.保存用户登录状态---session
                       //4.跳转回首页
       //		response.sendRedirect("http://www.easymall.com");
               response.sendRedirect(request.getContextPath()+"/");
               }
       
               public void doPost(HttpServletRequest request, HttpServletResponse response)
                       throws ServletException, IOException {
                       doGet(request, response);
       
               }
       
       }
      

      d. 修改login.jsp:添加如下代码


      <%
      //获取cookie中的remname 读取其中的用户名
      Cookie[] cs = request.getCookies();
      Cookie remnameC = null;
      //初次获取cookie数组为null
      if(cs !=null){
      for(Cookie c:cs){//遍历cookie数组,寻找remname这个cookie
      if(“remname”.equals(c.getName())){
      remnameC = c;
      }
      }
      }
      String username="";
      if(remnameC !=null){
      username = URLDecoder.decode(remnameC.getValue(), “utf-8”);

                       }
               
               
                %>
               
       <td><input type="text" name="username" value="<%=username%>"/></td>
       <input type="checkbox" name="remname"  value="true"
               <%="".equals(username)?"":"checked='checked'" %>	
               
               />记住用户名
      
    6. session概述
      在浏览器端保存数据,数据可以被查看、获取,数据安全性较低。重要的数据应该存放在不容易获取到的位置。服务器是一个良好的选择。数据通过服务器共享,这门技术就是session会话技术。

    7. Session工作原理
      每一个浏览器在访问服务器时,都会创建各自对应的session对象来保存数据。相互之间不会影响,是因为在session对象身上会包含一个sessionid,可以通过这个id来区分每一个浏览器对应的session。
      a. session工作原理:
      本质是通过一个名称为JSESSIONID的cookie来进行工作的。这个cookie会保存在浏览器中使用。
      b. session的特点:
      session是一门服务器的技术,将数据保存的服务器端。保存安全性要求较高的数据。且存储时间较短的数据。
      c. 创建session对象
      request.getSession();//如果服务器中有session对象,则取出使用,如果没有session对象则创建一个新的session对象使用。
      request.getSession(true);//如果服务器中有session对象,则取出使用,如果没有session对象则创建一个新的session对象使用。
      request.getSession(false);//如果服务器中没有session对象,则返回null,如果有session对想则取出使用。(判断session是否存在时使用)

    8. 作为域对象使用
      域对象:如果一个对象身上有一个可以被看见的范围,在这个范围内利用对象身上的map实现数据的共享,这个对象就可以称之为域对象。
      a. 操作api:
      setAttribute(String name,Object obj) 设置域属性
      getAttribute(String name) 获取域属性
      removeAttribute(String name ) 删除域属性
      getAttributeNames() 获取所有的域属性名称
      b. 生命周期:
      request.getSession()方法调用的时候session对象产生。
      i. 意外身亡:在服务器意外关闭的情况下,session对象会被销毁。在服务器正常关闭的情况下,如果session对象未被释放,则其中的内容会序列化到磁盘上,这个过程,称之为钝化。当服务器再次启动的时候,会重新读取磁盘上这个文件,这个过程称之为活化。
      ii. 自杀:主动session.invalidate()方法会立刻释放当前session对象。
      iii. 超时死亡:在[tomcat]/conf/web.xml中有session默认的最大生命时长配置标签,默认值为30分钟。超过30分钟,则当前session会被释放。
      c. 作用范围:
      整个会话范围。
      d. 主要功能:
      在整个会话范围内共享数据
      e. 代码实现:
      i. SessionDemo1.java
      package cn.tedu.session;

       	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;
       	//session共享数据--作为域对象使用
       	public class SessionDemo1 extends HttpServlet {
       	
       	        public void doGet(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                //1.获取session对象
       	                HttpSession session = request.getSession();
       	                //2.作为域对象使用--设置域属性
       	                session.setAttribute("name", "曹洋");
       	        }
       	
       	        public void doPost(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                doGet(request, response);
       	
       	        }
       	
       	}
       ii. SessionDemo2.java
       	package cn.tedu.session;
       	
       	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 class SessionDemo2 extends HttpServlet {
       	
       	        public void doGet(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                //1.获取session对象
       	                HttpSession session = request.getSession(true);
       	                //2.获取域属性
       	                String name = (String) session.getAttribute("name");
       	                System.out.println("name:"+name);
       	        }
       	
       	        public void doPost(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                doGet(request, response);
       	
       	        }
       	
       	}
      
    9. 案例:购物车
      两个Servlet:buyServlet/PayServlet
      一个jsp:sale.jsp — 挑选商品 点击商品名称加入购物车。点击付款按钮为商品结账。
      index.jsp页面
      <%@ page language=“java” import=“java.util.*” pageEncoding=“utf-8” session=“false”%>


       	  </head>
       	  
       	  <body>
       	    <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=鼠标">鼠标</a><br>
       	    <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=键盘">键盘</a><br>
       	    <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=月饼">月饼</a><br>
       	    <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=手机">手机</a><br>
       	    <a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=拖鞋">拖鞋</a><br>
       	    <a href="http://localhost/day12-cookiesession/servlet/PayServlet">付款</a><br>
       	  </body>
       	</html>
       buyServlet.java
       	package cn.tedu.session;
       	
       	import java.io.IOException;
       	
       	import javax.servlet.ServletException;
       	import javax.servlet.http.Cookie;
       	import javax.servlet.http.HttpServlet;
       	import javax.servlet.http.HttpServletRequest;
       	import javax.servlet.http.HttpServletResponse;
       	import javax.servlet.http.HttpSession;
       	//购物车Servlet
       	public class BuyServlet extends HttpServlet {
       	
       	        public void doGet(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                //1.请求乱码
       	                String prod = request.getParameter("prod");
       	                prod = new String(prod.getBytes("iso8859-1"),"utf-8");
       	                //2.响应乱码处理
       	                response.setContentType("text/html;charset=utf-8");
       	                
       	                //将商品放入购物车
       	                //1.获取session对象
       	                HttpSession session = request.getSession();
       	                //关闭浏览器前后都要操作同一个session
       	                //---在浏览器端保留一个名称为JSESSIONID的cookie,cookie值存储session的id
       	                Cookie cookie = new Cookie("JSESSIONID",session.getId());
       	                cookie.setMaxAge(60*60*24);
       	                cookie.setPath(request.getContextPath()+"/");
       	                response.addCookie(cookie);
       	                
       	                //2.向session中添加域属性
       	                session.setAttribute("prod", prod);
       	                //3.在浏览器中提示,商品加入购物车
       	                response.getWriter().write("商品【"+prod+"】已经加入购物车");
       	        }
       	
       	        public void doPost(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                doGet(request, response);
       	
       	        }
       	
       	}
       PayServlet.java
       	package cn.tedu.session;
       	
       	import java.io.IOException;
       	
       	import javax.servlet.ServletException;
       	import javax.servlet.http.HttpServlet;
       	import javax.servlet.http.HttpServletRequest;
       	import javax.servlet.http.HttpServletResponse;
       	//支付Servlet
       	public class PayServlet extends HttpServlet {
       	
       	        public void doGet(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                //从session中取出商品
       	                //1.响应乱码处理
       	                response.setContentType("text/html;charset=utf-8");
       	                //2.判断session是否存在--直接点击不会为任何商品付款
       	                if(request.getSession(false) != null){
       	                        //3.如果存在,则取出域属性
       	                        String prod = (String) request.getSession().getAttribute("prod");
       	                        //释放session,清空购物车。
       	                        request.getSession(false).invalidate();
       	                        //页面提示已为商品付款
       	                        response.getWriter().write("您以为商品【"+prod+"】付款¥10000");
       	                }else{
       	                        //4.如果不存在则提示用户尚未选择商品
       	                        response.getWriter().write("您尚未选择任何商品");
       	                }
       	        }
       	
       	        public void doPost(HttpServletRequest request, HttpServletResponse response)
       	                throws ServletException, IOException {
       	                doGet(request, response);
       	
       	        }
       	
       	}
      
    10. EasyMall功能–登录
      通过登录功能,保存用户的登录状态。
      request域~范围太小
      ServletContext域~范围太大
      session域–合适
      a. 修改LoginServlet.java,添加如下代码:
      //3.保存用户登录状态—session
      //判断用户名域密码是否匹配
      Connection conn = null;
      PreparedStatement ps = null;
      ResultSet rs = null;
      try {
      conn = JDBCUtils.getConnection();
      ps = conn.prepareStatement(“select * from user where username =? and password=?”);
      ps.setString(1, username);
      ps.setString(2, password);
      rs = ps.executeQuery();
      if(rs.next()){//用户名和密码正确,完成登录
      HttpSession session = request.getSession();
      session.setAttribute(“username”, username);
      }else{//返回登录页面作出提示
      request.setAttribute(“msg”, “用户名或密码不正确”);
      request.getRequestDispatcher("/login.jsp").forward(request, response);
      return;
      }
      } catch (SQLException e) {
      e.printStackTrace();
      }finally{
      JDBCUtils.close(conn, ps, rs);
      }

               //4.跳转回首页
       //		response.sendRedirect("http://www.easymall.com");
               response.sendRedirect(request.getContextPath()+"/");
      

      b. _head.jsp页面中添加如下内容:
      <%
      //判断是否存在登录状态
      if(request.getSession(false) != null
      && request.getSession().getAttribute(“username”)!=null){
      //第一个判断是确认session对象是否存在,如果存在仍然不能确定是否包含username域属性(登录状态)
      //第二个判断是确认当前session对象中是否包含username属性,如果包含才从中取出用户名,在页面中显示
      %>
      欢迎<%=request.getSession().getAttribute(“username”) %>,回来  |  
      注销
      <%
      }else{
      %>
      登录  |  
      注册
      <%
      }
      %>
      c. 在login.jsp中添加错误提示框

      <%=request.getAttribute(“msg”)==null?"":request.getAttribute(“msg”) %>

    11. 注销功能
      修改_head.jsp页面
      注销
      创建LogOutServlet.java
      package com.easymall.servlet;

      import java.io.IOException;

      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      //注销servlet
      public class LogOutServlet extends HttpServlet {

           public void doGet(HttpServletRequest request, HttpServletResponse response)
                   throws ServletException, IOException {
                   //注销用户就是销毁session
                   if(request.getSession(false) !=null){
                           
                           request.getSession().invalidate();
                   }
                   //跳转回首页
                   response.sendRedirect(request.getContextPath()+"/");
                   
           }
      
           public void doPost(HttpServletRequest request, HttpServletResponse response)
                   throws ServletException, IOException {
                   doGet(request, response);
      
           }
      

      }

    12. 验证码实现
      a. 在ValidateServlet中添加如下内容:
      response.setDateHeader(“Expires”, -1);
      response.setHeader(“Cache-Control”, “no-cache”);
      VerifyCode vc = new VerifyCode();
      //当前servlet只有img标签调用,所以将图片放入缓冲区,
      //最终会在其调用的位置输出在浏览器中。
      vc.drawImage(response.getOutputStream());
      String code = vc.getCode();
      //添加验证码到session域
      request.getSession().setAttribute(“code”, code);
      System.out.println(code);
      System.out.println(“执行成功~!”);
      b. 在registServlet中添加如下内容:
      //6.验证码校验
      //TODO:session
      //获取域中验证码和用户输入的验证码,作比对
      String code = (String) request.getSession().getAttribute(“code”);
      if(!code.equalsIgnoreCase(valistr)){
      request.setAttribute(“msg”, “验证码错误”);
      request.getRequestDispatcher("/regist.jsp").forward(request, response);
      return;
      }

    13. Cookie特点:
      cookie是将数据保存在浏览器端,是一门浏览器端的技术。由于数据保存在浏览器端,所以可以被任意的查看,安全性较低,但是可以长时间存储数据。cookie善于存储安全性要求较低,但是存储时间较长的数据。

    14. Session特点:
      session是将数据保存在服务器端,是一门服务器端的技术,数据保存在服务器端相对安全,但是服务器无法保留大量session对象,所以不能够长时间存储数据。服务器善于存储安全性要求较高,但是存储时间较短的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值