zoukankan      html  css  js  c++  java
  • HttpSession 入门

    1. HttpSession 概述

    • 位于 javax.servlet.http 包;
    • HttpSession 是由 JavaWeb 提供的功能, 用来会话跟踪的类, session 是服务器端对象, 保存在服务器端!!!
    • HttpSession 底层依赖 Cookie, 或是 URL 重写!

    2. HttpSession 的作用

    1. 会话范围: 从某个用户首次访问服务器开始, 到该用户关闭浏览器结束!
      • 会话: 一个用户对服务器的多次连贯性请求! 所谓连贯性请求, 就是该用户多次请求中间没有关闭浏览器!
    2. 服务器会为每个用户创建一个 Session 对象, session 就好比用户在服务器端的账户, 它们被服务器保存到
      一个 Map 中, 这个 Map 被称之为 session 的缓存.
      - Servlet 中得到 session 对象: HttpSession session = request.getSession();
      - JSP 中得到 session 对象: session 是 JSP 内置对象之一, 不用创建就可以直接使用!
    3. session 域相关方法:
      • void setAttribute(String name, Object value);
      • Object getAttribute(String name); : 返回值为 Object 类型, 需要强转!
      • void removeAttribute(String name);

    // 示例: 保存用户登录信息
        /*
         * 相关页面和 Servlet
         *   login.jsp: 登录页面
         *   succ1.jsp: 只有登录成功才能访问的页面
         *   LoginServlet: 校验用户是否登录成功
         *
         * 各页面和 Servlet 内容:
         *    login.jsp: 提供登录表单, 将表单请求数据提供给 LoginServlet, 如果登录失败,需要显示错误信息
         *    LoginServlet: 获取请求参数, 校验用户是否登录成功
         *         失败: 保存错误信息到 request 域, 转发到 login.jsp( login.jsp 显示 request 域中的错误信息)
         *         成功: 保存用户信息到 session 域中, 重定向到 succ1.jsp 页面, 显示 session 域中的用户信息
         *
         *    succ1.jsp: 从 session 域获取用户信息, 如果不存在, 显示"您还没有登录", 存在则显示用户信息
         *    succ2.jsp: 从 session 域获取用户信息, 如果不存在, 显示"您还没有登录", 存在则显示用户信息
         *    
         * 只要用户没有关闭浏览器, session 就一直存在, 那么保存在 session 中的用户信息也就一直存在! 那么用户访问
         * succ1 就会成功!
         *
         * 附加项(浏览器保存用户信息):
         *     把用户名保存到 cookie 中, 发送给客户端浏览器
         *     当再次打开 login.jsp 时, login.jsp 会读取 request 中的 cookie, 把它显示到用户名文本框中.
         */
    
    // login.jsp
    
        <head>
            // 换一张的函数
            <script type="text/javascript">
                function _change(){
                    // 获取 img 节点
                      var imgEle = document.getElementById("img");
                    // 对该节点的 src 属性重新赋值
                    imgEle.src = "/day11_1/VerifyCodeServlet?a="+new Date().getTime();
                } 
            </script>
        </head>
    
    
        <body>
            // 获取 cookie 中的信息
            <%
                // 定义变量, 并赋值为空
                String uname = "";
                Cookie[] cks = request.getCookies();
                // 如果有 cookie 存在
                if(cks != null){
                        // 遍历数组
                        for(Cookie ck:cks){
                                if("uname".equals(ck.getName())){
                                uname = ck.getValue();
                                }
                        }
                }
            %>
    
            // 显示错误信息
            <%
                String message = "";
                String msg = (String)request.getAttribute("msg");
                if(msg != null){
                    message = msg;
                }
            %>
    
    
            <h1>登录</h1>
            // 显示错误信息
            <font color="red"><b><%=message %></b></font>
    
            // 正常表单
            <form action="" method="POST">
                // 注意: <%=uname %> 需要使用引号引起来
                // value 是 cookie 中的用户名, 显示到文本框中
                用户名:<input type="text" name="username" value="<%=uname %>"/><br/>
                密 码:<input type="password" name="psw"/><br/>
                验证码:<input type="text" name="verifyCode" size="3"/>
                         <img id="img" src="/day11_1/VerifyCodeServlet" />
                         <a href="javascript:_change()">换一张</a><br/>
                <input type="submit" value="提交"/>
            </form>
        </body>
    
    // LoginServlet
            public void doPost(HttpServletRequest request, HttpServletResponse response){
                //首先处理 POST 编码问题
                request.setCharacterEncoding("uft-8");
    
                // 获取 request 请求表单中的数据, 不是 request 域
                String name = request.getParameter("username");
    
                // 获取 session 域中验证码数据
                String sessionCode = request.getSession().getAttribute("session_vcode");
                // 获取 request 请求中的验证码
                String paramCode = request.getParamter("verifyCode");
                // 比较两者
                if(!paramCode.equalsIgnoreCase(sessionCode)){
                    request.setAttribute("msg","您填写的验证码有误!");
                    //转发
                    request.getRequestDispatcher("login.jsp").forward(request,response);
                    return;
                }
    
                // 判断,只要不是 "itcast",就能登录成功, 重定向至 succ1.jsp
                // 否则,保存错误信息到 request域中, 转发至 login.jsp
                if(!"itcast".equalsIgnoreCase(name)){
                    // 附加项: 浏览器保存用户信息, 方便第二次登录
                    Cookie ck = new Cookie("uname",name);
                    ck.setMaxAge(60*60*24);  // 最长在浏览器保存 1 天
                    response.addCookie(ck);
    
                    // 获取 session 域
                    HttpSession session = request.getSession();
                    // 保存用户名到session域
                    session.setAttribute("username",name);
                    // 重定向到 succ1.jsp, 路径中需要加入项目名
                    response.sendRedirect("/day11_1/succ1.jsp");
                } else {
                    // 保存错误信息到 request 域
                    request.setAttribute("msg","用户名或密码错误!");
                    // 转发至login.jsp
                    request.getRequestDispatcher("/login.jsp").forward(request,response);
                }
            }
    
    // VerifyCodeServlet
            public class VerifyCodeServlet extends HttpServlet{
                    pubilc void doGet{
                        VerifyCode vc = new VerifyCode();
                        BufferedImage bi = vc.getImage();
                        // 将图片中的文本保存到 session 域中
                        request.getSession().setAttribute("session_vcode",vc.getText());
                        // 将图片显示在 login.jsp 页面
                        VerifyCode.output(bi,response.getOutputStream());
                    }
            }
    
    // succ1.jsp
        <body>
        // 如果用户通过输入地址来访问该页面, 需要判断 session 中的用户名
            <%
                String name = (String)session.getAttribute("username");
                if(name == null){
                    // 保存错误信息
                    request.setAttribute("msg","您还没有登录!");
    
                    // 转发到 login.jsp, 留头不留体
                    request.getRequestDispatcher("/login.jsp").forward(request,response);
                    // 结束程序, 下面的内容不会输出
                    return;
                }
            %>
            <h1>Succ1</h1>
            欢迎<%=name %>光临本网站!!
        </body>
    

    3. HttpSession 原理

    • 如果 sessionId 不存在, 服务器创建 session 对象, 把 session 保存起来, 把新创建的 sessionID 保存到 Cookie 中;
    • 如果 sessionId 存在, 通过 sessionId 查找 session 对象, 如果没有找到, 创建 session, 把 session 保存
      起来, 把新创建的 sessionId 保存到 Cookie 中;
    • 如果 sessionId 存在, 通过 sessionId 查找到了 session 对象, 那么就不会创建 session 对象了.
    • 返回 session 对象

    备注: session 对象存储在服务器端的 Map 集合中, 键为:sessionId, 值为: session 对象.

    1. 如果创建了新的 session, 浏览器会得到一个包含了 sessionId 的 Cookie, 这个 Cookie 的生命为 -1,
      即只在浏览器内存中存在. 浏览器关闭后,该 Cookie 会被删除.

    2. 服务器并不会在访问页面时,马上给你创建 session 对象, 只有在第一次获取 session 对象时, 才会调用
      request.getSession()方法创建 session 对象.

      • 访问 ".jsp" 文件会自动调用 request.getSession(); 方法;
      • 访问 Servlet 页面, 需要人工写入 request.getSession(); 方法.
    3. 多次请求: 如果第一次请求创建了 session 对象. 第二次请求, 服务器端再次执行 request.getSession()
      法,服务器端可以通过 Cookie 中的 JSESSIONID 找到第一次请求创建的 session 对象. 所以与上一次请求使
      用的是同一个 session 对象.

    4. 方法比较:

      • request.getSession(true); : 与 request.getSession(); 效果相同;
      • request.getSession(false);: 如果 session 缓存中,不存在 session,返回 null,而不会创建 session
        对象. 如果 cookie 不存在, 也不会创建 session 对象.

    4. HttpSession 其他方法

    • String getId(); : 获取 sessionId(32 位长字符串);
    • int getMaxInactiveInterval(); : 获取 session 对象的最大不活动时间(秒), 默认为 30 分钟;
      当 session 对象在30分钟内没有使用, 那么会被 Tomcat 从 session 池中移除.
    • void invalidate(); : 让 session 失效!
    • boolean isNew(); : 查看 session 对象是否为新
    // 获取 UUID, 也就是 sessionId
    // J2SE 中的 java.util 中有 UUID 类
    UUID uuid = UUID.randomUUID();
    String str = uuid.toString();
    str = str.replace("-","");
    str = str.toUpperCase();
    

    5. web.xml 中配置 session 的最大不活动时间(分钟)

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

    6. URL 重写 (理解)

    • session 依赖 Cookie, 目的是让客户端发送请求时,归还 sessionId, 这样才可能找到对应的 session 对象;
    • 如果客户端禁用了 Cookie, 那么就无法得到 sessionId, 那么 session 也就没法使用了!
    • 这时, 可以使用 URL 重写来替代 Cookie
      • 让网站的所有超链接, 和表单中都添加一个特殊的请求参数, 即 sessionId;
      • 这样服务器可以通过获取请求参数得到 sessionId, 从而找到 session 对象;
    • response.encodeURL(String url);
      • 该方法会对 url 进行智能的重写, 当请求中没有归还 sessionId 这个 cookie, 那么该方法会重写 url,
        在指定的 url 后添加 JESSIONID 参数. 否则, 不会重写.

    参考资料:

  • 相关阅读:
    ubuntu: no module named _sqlite
    mysql慢查询分析工具 pt-query-digest
    vue中的时间修饰符stop,self
    面试题 —— Ajax的基本原理总结
    es6笔记 day6-Symbol & generator
    类(class)和继承
    es6笔记 day4---模块化
    es6笔记 day3---Promise
    es6笔记 day3---对象简介语法以及对象新增
    es6笔记 day3---数组新增东西
  • 原文地址:https://www.cnblogs.com/linkworld/p/7593713.html
Copyright © 2011-2022 走看看