会话技术Cookie&Session

1会话技术简介

1.1存储客户端的状态

例如网站的购物系统,因为Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并不知道该客户端是谁,所以需要会话技术识别客户端的状态。

会话技术是帮助服务器记住客户端状态(区分客户端)的。

 

1.2会话技术

从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,成为一次会话。

注意是关闭浏览器,不是只关闭浏览器的标签。

会话技术就是记录这次会话中客户端的状态与数据的。

会话技术分为CookieSession

Cookie:数据存储在客户端本地,减少服务器端的存储压力,安全性不好(例如在公共电脑访问,容易泄露信息),客户端可以清除cookie

Session:将数据存储到服务器端,安全性相对好,但会增加服务器的压力。

两者结合起来使用最好。

 

2 Cookie技术

以响应头的形式发送给客户端,键值对方式存,不能存储中文,setHeader

 

请求头把值传给服务器,用getHeader获取

 

 

关注点:

1)服务器怎样将一个cookie写给客户端

2)服务器怎样获取客户端携带的cookie

 

2.1服务器端向客户端发送一个Cookie

1)创建Cookie对象

2)将Cookie中存储的信息发送到客户端

 

例:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //向客户端发送Cookie
        //1创建Cookie对象
        Cookie cookie=new Cookie("goods","vivo");        
        //2将Cookie中存储的信息发送到客户端
        response.addCookie(cookie);        
    }

访问 http://localhost:8080/20190112WEB/SendCookieServlet,抓包

 

 

再访问一次,

  

 

再访问http://localhost:8080/20190112WEB/index.jsp,还在

 

 

重新开一个标签,访问http://localhost:8080/20190112WEB/index.jsp,数据还在

 

关闭浏览器,再开,没有了

 

 

3)设置Cookie在客户端的持久化时间

cookie.setMaxAge(int seconds); ----时间秒

如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭cookie信息销毁(会话级别的cookie),

如果设置持久化时间,cookie信息会被持久化到浏览器的磁盘文件里

过期浏览器自动删除该cookie信息 

例:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //向客户端发送Cookie
        //1创建Cookie对象
        Cookie cookie=new Cookie("goods","vivo");
        //设置Cookie持久化时间
        cookie.setMaxAge(120);        
        //2将Cookie中存储的信息发送到客户端
        response.addCookie(cookie);        
    }

访问 http://localhost:8080/20190112WEB/SendCookieServlet,

再访问 http://localhost:8080/20190112WEB/index.jsp

关闭浏览器,再开,再访问http://localhost:8080/20190112WEB/index.jsp

 

 

4)设置Cookie的携带路径

cookie.setPath(String path); 相对路径

例:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //向客户端发送Cookie
        //1创建Cookie对象
        Cookie cookie=new Cookie("goods","vivo");        
        //设置Cookie的携带路径
        cookie.setPath("/20190112WEB");
        //2将Cookie中存储的信息发送到客户端
        response.addCookie(cookie);        
    }

结果:

http://localhost:8080/20190112WEB/SendCookieServlet (有)

http://localhost:8080/20190112WEB/index.jsp (没有)

 

Tips

1)只写项目路径/20190112WEB,那么就是访问该项目下所有资源时都携带

2)如果写 / ,那么是访问服务器上所有资源时携带(服务器上可能有多个项目)

3)如果不设置携带路径,那么该cookie信息会在访问产生该cookieweb资源所在的路径都携带cookie信息

(产生该cookieweb资源:http://localhost:8080/20190112WEB/SendCookieServlet

   所在的路径:http://localhost:8080/20190112WEB/ 

 

例:

把web.xml改为:

 

结果:

http://localhost:8080/20190112WEB/demo/SendCookieServlet (产生cookie

http://localhost:8080/20190112WEB/index.jsp (没有)

http://localhost:8080/20190112WEB/demo/index.jsp  (有)

 

5)删除客户端的cookie

如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时间为0cookie进行覆盖即可

例:

SendCookieServlet

  

 

removeCookieServlet

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //删除客户端的cookie
        //创建Cookie对象
        Cookie cookie=new Cookie("goods", "vivo");
        //设置Cookie的携带路径
        cookie.setPath("/20190112WEB");
        //设置Cookie持久化时间
        cookie.setMaxAge(0);
        response.addCookie(cookie);
    }

依次访问:

http://localhost:8080/20190112WEB/SendCookieServlet(产生)

http://localhost:8080/20190112WEB/index.jsp(有)

http://localhost:8080/20190112WEB/removeCookieServlet

http://localhost:8080/20190112WEB/index.jsp(没有了)

 

2.2服务器端怎么接受客户端携带的Cookie

cookie信息是以请求头的方式发送到服务器端的。

1)通过request获得所有的Cookie

2)遍历Cookie数组,通过Cookie的名称获得我们想要的Cookie 

例:

getCookieServlet

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取客户端携带的所有cookie数据
        Cookie[] cookies=request.getCookies();
        //通过cookie名称得到相应的值
        if(cookies!=null){
            for(Cookie c:cookies){
                String cookName=c.getName();
                if(cookName.equals("goods")){
                    String cookValue=c.getValue();
                    System.out.println(cookValue);
                }
            }
        }
    }

访问:

http://localhost:8080/20190112WEB/SendCookieServlet

http://localhost:8080/20190112WEB/getCookieServlet

 

注意必须在cookie携带路径上才能获取到

 

2.3示例:记录上一次访问时间

判断cookie为空,则为第一次。存一个cookie记录时间

第二次,携带过来时间,再存一个时间 

 

AccessServlet

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取当前时间
        Date date=new Date();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String currentTime=sdf.format(date);//日期对象转字符串
        //创建cookie
        Cookie cookie=new Cookie("lastTime", currentTime);
        cookie.setMaxAge(60*10); //10分钟
        //发送cookie
        response.addCookie(cookie);    
        
        //获得客户端携带cookie---上次访问时间
        Cookie[] cookies=request.getCookies();
        String lastTime=null; //上次访问时间
        if(cookies!=null){            
            for(Cookie c:cookies){
                if(c.getName().equals("lastTime")){
                    lastTime=c.getValue(); //获取值
                }
            }
        }
        
        //解决中文乱码
        response.setContentType("text/html;charset=utf-8");
        
        if(lastTime==null){
            //第一次访问
            response.getWriter().write("您是第一次访问");
        }else{
            response.getWriter().write("您上次访问的时间为"+lastTime);
        }        
    }

 

3 Session技术

Session技术是将数据存储在服务器端的技术,会为每个客户端都创建一块内存空间存储客户的数据,

但客户端需要每次都携带一个标识ID去服务器中寻找属于自己的内存空间。

所以Session的实现是基于Cookie的,Session需要借助Cookie存储客户的唯一性标识JSESSIONID

 

关注三个问题:

1)怎样创建专属于客户端的session区域

2)怎样向session中存取数据

3)session生命周期

 

发送jsessionid和根据该编号找session域由客户端自己完成,不用关注

 

 

 

3.1获得Session对象

HttpSession session = request.getSession();

此方法会获得专属于当前会话的Session对象,如果服务器端没有该会话的Session 对象会创建一个新的Session返回;

如果已经有了属于该会话的Session直接将已有的Session返回(实质就是根据JSESSIONID判断该客户端是否在服务器上已经存在session了)

 

例:

Servlet01

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session对象(开辟一块session区域)
        HttpSession session=request.getSession();        
        //获取Jsessionid
        String id=session.getId();
        response.getWriter().write("Jsessionid:"+id); //写到前台
    }

 

刷新,id也不变

 

关闭浏览器后,再开,则变化了,因为客户端的jsessionid随着会话结束而消失,所以又开辟了一块新的session

 

3.2怎样向session中存取数据

session也是一个域对象。(域对象就是在服务器上的存储对象,所以cookie不是域对象。)

三个方法:

session.setAttribute(String name,Object obj);

session.getAttribute(String name);

session.removeAttribute(String name);

 

例:

Servlet01

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session对象(开辟一块session区域)
        HttpSession session=request.getSession();
        //存储数据
        session.setAttribute("goods", "iphone");
        //获取Jsessionid
        String id=session.getId();
        response.getWriter().write("Jsessionid:"+id); //写到前台
    }

 

Servlet02

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session对象
        HttpSession session=request.getSession(); //和Servlet01那里的是同一个对象
        //取值
        String value=(String) session.getAttribute("goods"); //强转
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("goods:"+value);        
    }

 

先访问Servlet01,再Servlet02

  

换个浏览器(或关了重开),只访问Servlet02

 

 

3.3持久化存储jsessionid

利用cookie

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session对象
        HttpSession session=request.getSession();
        session.setAttribute("name", "小野猪");
        String id=session.getId();
        //手动创建一个存储Jsessionid的cookie对象
        Cookie cookie=new Cookie("JSESSIONID", id);
        cookie.setPath("/20190112WEB");
        cookie.setMaxAge(60*3);
        //发送cookie对象
        response.addCookie(cookie);
        response.getWriter().write("JSESSIONID:"+id);
    }

关闭浏览器重开,还在。

 

3.4 Session对象的生命周期

创建:第一次执行request.getSession()时创建

销毁:

1)服务器(正常/非正常)关闭时

2session过期/失效(默认30分钟)

  时间的起算点从不操作服务器端的资源开始计时

  可以在web.xml中进行配置(以覆盖服务器上的时间)

  <session-config>

    <session-timeout>30</session-timeout>

  </session-config>

 

3)手动销毁session

session.invalidate();( 一般不会销毁)

 

作用范围:

默认在一次会话中(在一次会话中任何资源公用一个session对象)

 

4 验证码验证

(之前做的验证码例子和登录的例子)

 

//获取用户输入验证码
String code=request.getParameter("code");
//获取session中正确的验证码
        String scode=(String) request.getSession().getAttribute("checkcode_session");
        if(!code.equals(scode)){
            request.setAttribute("loginInfo", "验证码输入错误");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
            return; //结束方法,下方代码不再执行
        }    

 

重点总结:

1 Cookie

1)发送cookie

获得对象:Cookie cookie = new Cookie(name,value)

持久化时间:cookie.setMaxAge()

携带路径:cookie.setPath()

发送:response.addCookie(cookie)

2)获得cookie

Cookie[] cookies = request.getCookies();

cookie.getName();

cookie.getValue();

2 Session

1)获得对象:HttpSession session = request.getSession();

获得JSESSIONIDsession.getId();

2)存取数据:

setAttribute(name,value);

getAttribute(name);

3)生命周期

创建:第一次指定request.getSession();

销毁:服务器关闭、session失效/过期、手动session.invalidate();

作用范围:默认一次会话中

3两个实例:记录上一次访问时间和验证码验证

 

posted @ 2019-01-12 17:00  后知后觉0107  阅读(202)  评论(0编辑  收藏  举报