会话跟踪技术

作者: 咸鱼有梦想呀 | 来源:发表于2018-07-31 18:02 被阅读14次

    一、会话跟踪技术

    在JavaWeb中,客户向某一服务器发出第一个请求开始,会话就开始了,直到客户关闭了浏览器会话结束。

    在一个会话的多个请求中共享数据,这就是会话跟踪技术

    会话路径技术使用Cookie或session完成
    我们知道HTTP协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态。但HTTP协议中可以使用Cookie来完成会话跟踪!
    在JavaWeb中,使用session来完成会话跟踪,session底层依赖Cookie技术。

    二、Cookie

    Cookie是HTTP协议制定的
    Cookie就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。

    Cookie是不能跨浏览器的
    Cookie中不能存在中文

    Cookie

    Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了!

    1.HTTP的Cookie规范

    • 1个Cookie的大小不超过4KB
    • 1个服务器最多向1个浏览器保存20个Cookie
    • 1个浏览器最多可以保存300个Cookie

    2.Cookie的用途

    • 服务器使用Cookie来跟踪客户端状态
    • 保存购物车
    • 显示上次登录名

    3.Cookie与HTTP头
    Cookie是通过HTTP请求和响应头在客户端和服务器端传递的

    • Cookie:
      请求头,客户端发送给服务器端。
      格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;

    • Set-Cookie
      响应头,服务器端发送给客户端
      一个Cookie对象一个Set-Cookie:
      Set-Cookie: a=A
      Set-Cookie: b=B
      Set-Cookie: c=C

    4.Cookie的覆盖
    如果服务器端发送重复的Cookie那么会覆盖原有的Cookie。

    5.JavaWeb中使用Cookie

    • 原始方法
      • 使用response发送Set-Cookie响应头
      • 使用request获取Cookie请求头
    • 便捷方法
      • 使用response.addCookie()方法向浏览器保存Cookie
      • 使用request.getCookies()方法获取浏览器归还的Cookie

    代码说明:
    一个jsp保存cookie, a.jsp
    另一个jsp获取浏览器归还的cookie! b.jsp

    a.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>保存Cookie</h1>
    <%
        Cookie cookie1 = new Cookie("aaa", "AAA");
        response.addCookie(cookie1);
    
        Cookie cookie2 = new Cookie("bbb", "BBB");
        response.addCookie(cookie2);
    %>
    </body>
    </html>
    
    
    保存Cookie

    b.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>获取Cookie</h1>
    <%
        Cookie[] cookies = request.getCookies();
        if(cookies != null) {
            for(Cookie c : cookies) {
                out.print(c.getName() + "=" + c.getValue() + "<br/>");
            }
        }
    %>
    </body>
    </html>
    
    
    获取Cookie

    6.Cookie的生命
    Cookie不只是有name和value,Cookie还是生命。所谓生命就是Cookie在客户端的有效时间,可以通过setMaxAge(int)来设置Cookie的有效时间。
    已秒为单位。不设置——默认为关闭窗口,Cookie结束。

    • cookie. setMaxAge(-1):cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。
    • cookie.setMaxAge(60*60):表示cookie对象可存活1小时。当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie也会存活1小时;
    • cookie.setMaxAge(0):cookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。

    7.Cookie的路径
    Cookie的path由服务器创建Cookie时设置
    当浏览器访问服务器某个路径时,需要归还哪些Cookie给服务器呢?这由Cookie的path决定。
    浏览器访问服务器的路径,如果包含某个Cookie的路径,那么就会归还这个Cookie。

    例如:
    aCookie.path=/day11_1/; bCookie.path=/day11_1/jsps/; cCookie.path=/day11_1/jsps/cookie/;
    访问:

    • /day11_1/index.jsp时,归还:aCookie
    • 访问:/day11_1/jsps/a.jsp时,归还:aCookie、bCookie
    • 访问:/day11_1/jsps/cookie/b.jsp时,归还:aCookie、bCookie、cCookie

    Cookie的path默认值:当前访问路径的父路径。例如在访问/day11_1/jsps/a.jsp时,响应的cookie,那么这个cookie的默认path为/day11_1/jsps/

    8.Cookie的domain(域)
    domain用来指定Cookie的域名!当多个二级域中共享Cookie时才有用。

    例如:
    www.baidu.comzhidao.baidu.comnews.baidu.comtieba.baidu.com之间共享Cookie时可以使用domain
    1)设置domain为:cookie.setDomain(".baidu.com");
    2)设置path为:cookie.setPath("/");

    三、HttpSession

    HttpSession是由JavaWeb提供的,用来会话跟踪的类,session是服务器端对象,保存在服务器端中。
    HttpSession是Servlet三大域对象之一

    1.HttpSession的会话范围
    会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束!

    2.获取HttpSession对象

    • Servlet中获取HttpSession对象
      HttpSession session = request.getSesssion():如果当前会话已经有了session对象那么直接返回,如果当前会话还不存在会话,那么创建session并返回;

    • jsp中获取HttpSession对象
      session是jsp内置对象之下,不用创建就可以直接使用

    3.session域相关方法

    • void setAttribute(String name, Object value):
      用来存储一个对象,也可以称之为存储一个域属性。
    • Object getAttribute(String name):
      用来获取session中的数据,当前在获取之前需要先去存储才行。
    • void removeAttribute(String name):
      用来移除HttpSession中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做。

    小栗子

    登录案例
    1.思路整理:

    登录案例思路整理
    • login.jsp
      提供登录表单
      表单指向LoginServlet

    • success1.jsp(登录用户可以访问)
      1)从session中获取用户信息,如果存在说明已经登录,显示用户名
      2)如果不存在,向request域保存错误信息,转发到login.jsp

    • LoginServlet
      1)获取表单数据
      2)效验用户名和密码是否正确
      3)成功:保存用户信息到session中,重定向到success1.jsp
      4)失败:保存错误信息到request域,转发回login.jsp

    2.代码实现
    login.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录页面</title>
    </head>
    <body>
    
    <%-- 登录表单及错误信息显示 --%>
    
    <h1>登录</h1>
    <%-- 附加功能 --%>
    <%
        /**
         * 读取名为uname的Cookie!
         * 如果为空显示:""
         * 如果不为空显示:Cookie的值
         */
        String uname = "";
        Cookie[] cookies = request.getCookies();//获取请求中所有的cookie
        if (cookies != null){// 如果存在cookie
            for (Cookie cookie : cookies){//循环遍历所有的cookie
                if ("uname".equals(cookie.getName())){//查找名为uname的cookie
                    uname = cookie.getValue();//获取这个cookie的值,给uname这个变量
                }
            }
        }
    
    %>
    
    
    <%
        String message = "";
        String msg = (String)request.getAttribute("msg");//获取request域中的名为msg的属性
        if (msg != null){
            message = msg;
        }
    %>
    
    <p style="color: brown"><b><%=message %></b></p>
    <%-- action中"/项目名/<url-pattern>" --%>
    <form action="/visitCount/LoginServlet" method="post">
        <%-- 把cookie中的用户名显示到用户名文本框中 --%>
        用户名:<input type="text" name="username" value="<%=uname %>">
        密码:<input type="password" name="pwd">
    <input type="submit" value="登录">
    </form>
    </body>
    </html>
    
    

    LoginServlet

    package login;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.*;
    import java.io.IOException;
    
    @WebServlet(name = "LoginServlet")
    public class LoginServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            /**
             * 1.获取表单数据
             */
            //处理中文
            request.setCharacterEncoding("utf-8");
            //获取
            String username = request.getParameter("username");
            String pwd =  request.getParameter("pwd");
            /**
             * 2.验证用户名和密码是否正确
             */
            if (!"admin".equalsIgnoreCase(username)){
                //登录成功
                /**
                 * 附加功能:把用户名保存到cookie中,发送给客户端浏览器
                 * 再次打开login.jsp时,login.jsp中会读取request中的cookie,把它显示到用户名文本框中
                 */
                Cookie cookie = new Cookie("uname",username);//创建Cookie
                cookie.setMaxAge(60*60*24);//设置Cookie的时长为一天
                response.addCookie(cookie);//保存cookie
    
                /**
                 * a.保存用户信息到session中
                 * b.重定向到success1.jsp
                 */
                HttpSession session = request.getSession();//获取seession
                session.setAttribute("usuername",username);//向session域中保存用户名
                response.sendRedirect("/visitCount/success1.jsp");
            }else {
                //登录失败
                /**
                 * a.保存错误信息到request域中
                 * b.转发到login.jsp
                 */
                request.setAttribute("msg","用户名或密码错误");
                RequestDispatcher requestDispatcher = request.getRequestDispatcher("/login.jsp");//得到转发器
                requestDispatcher.forward(request,response);//转发
            }
    
    
        }
    
    }
    
    

    success1.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>登录成功</h1>
    <%-- session拦截未登录的用户 --%>
    <%
        String username = (String)session.getAttribute("username");
        if (username == null){
            /**
             * 向request域中发送错误信息,转发到login.jsp
             */
            request.setAttribute("msg","请登录");
            request.getRequestDispatcher("login.jsp").forward(request,response);
            return;
        }
    %>
    欢迎<%=username %>
    
    </body>
    </html>
    
    

    相关文章

      网友评论

        本文标题:会话跟踪技术

        本文链接:https://www.haomeiwen.com/subject/jxlpmftx.html