zoukankan      html  css  js  c++  java
  • JSP 状态管理 -- Session 和 Cookie

    Http 协议的无状态性

    无状态是指,当浏览器发送请求给服务器的时候,服务器响应客户端请求。但是同一个浏览器再次发送请求给服务器的时候,服务器并不知道它就是刚才那个浏览器

    session

    • session表示客户端与服务器的一次对话
    • Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间
    • 从上述定义中可以看到,session实际上是一个特定的时间概念

    在服务器的内存中保存着不同用户的session,也就是说每一个用户对应着一个session,不同的用户对应着不同的session

    • session 对象是一个JSP内置对象
    • session对象在第一个JSP页面被加载时自动创建,用来完成会话期管理
    • 从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这个服务器结束,被称为一个会话
    • 当一个客户访问一个服务器时,可能会在服务器的几个页面之间切换,服务器应当通过某种办法这是一个客户,就需要session对象
    • session对象是HttpSession类的实例

    session 对象常用方法:

    • long getCreationTime(): 返回 session 创建时间
    • public String getId(): 返回 session 创建时,JSP 引擎为它设的唯一ID号
    • public Object setAttribute( String name, Object value): 使用指定名称将对象绑定到此会话
    • public Object getAttribute( String name ): 返回与此会话中的指定名称绑定在一起的对象,如果没有对象绑定在该名称下,则返回 null
    • String[] getValueNames(): 返回一个包含次此 session 中所有可用属性的数组
    • int getMaxInactiveInterval(): 返回两次请求间隔多长时间此 session 被取消(单位:秒)
    <%@ page language="java" import="java.text.*, java.util.*" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
    </head>
    <body>
    <%
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
        Date d = new Date(session.getCreationTime());
        session.setAttribute("username", "Kobe");
    %>
    
    session 的创建时间:<%=sdf.format(d) %><br> <%--session.getCreationTime() 返回的是一个毫秒数 --%>
    <%--new Date(session.getCreationTime()) Thu Mar 08 09:57:56 CST 2018 --%>
    session ID: <%=session.getId() %><br>
    获取用户名:<%=session.getAttribute("username") %>
    </body>
    </html>

    页面运行结果:

    现在原来的 session.jsp 代码中添加一个超链接,用来体现从进入网站到浏览器关闭期间,是同一次会话,注意观察 sessionID 是否发生改变,如果发生改变则证明不是同一次会话,如果不变则证明是同一次会话

    <a href="session2.jsp" target="_blank">跳转到 session2.jsp 页面</a>

    同时,创建一个新的页面 session2.jsp,查看 sessionID 以及能否拿到同一次会话中服务器保存的username 属性

    <%@ page language="java" import="java.text.*, java.util.*" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    session ID: <%=session.getId() %><br>
    获取用户名:<%=session.getAttribute("username") %>
    </body>
    </html>

    注意查看id 和 username

    现在演示下 session.getValueNames() 的用法

    在session.jsp 中另外添加两个属性,password 和 age

    <%
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
        Date d = new Date(session.getCreationTime());
        session.setAttribute("username", "Kobe");
        // 新增加两个属性 password 和 age
        session.setAttribute("password", "123456");
        session.setAttribute("age", 28);
    %>

    在session2.jsp 中来查看有哪些可用的属性

    session ID: <%=session.getId() %><br>
    session 中保存的用户名:<%=session.getAttribute("username") %><br>
    session 中保存的属性有:
    <%
        String[] names = session.getValueNames();
        for (String name:names){
            out.println(name + "&nbsp;&nbsp;");
        }
    %>

    页面结果:

    再来看下如何设置session的过期时间,session.jsp

    <%
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
        Date d = new Date(session.getCreationTime());
        session.setAttribute("username", "Kobe");
        // 新增加两个属性 password 和 age
        session.setAttribute("password", "123456");
        session.setAttribute("age", 28);
        
        // session.setMaxInactiveInterval() 设置 session的过期时间,单位秒
        session.setMaxInactiveInterval(3);
    %>

    再次点击超链接时,我们发现sessionID改变了,属性值为null,属性没有,说明这是一个新的会话。也就是说间隔3秒以后,原来的session过期了

    session 生命周期

    创建 ---> 活动 ---> 销毁

    1、创建

    2、活动(新的 session启动并不意味着旧的session已经关闭)

    3、销毁

    Tomcat 默认 session超时时间为 30分钟,设置 session 超时有两种方式:

    1、session.setIntactiveInterval(时间); // 单位:秒

    2、在 web.xml 配置

    <session-config>
        <session-timeout> 10 </session-timeout>
    </session-config> // 单位:分钟

    Cookie

    中文名称为“小甜饼”,是Web服务器保存在 客户端 的一系列文本信息。Cookie 是键值对形式存储的少量信息

    作用:

    平时上网时都是使用 无状态的HTTP协议输出数据,这意味着客户端与服务端在数据传送完成后就会中断连接。这时我们就需要一个一直保持会话连接的机制,在session出现之前,cookie就完全充当了这个角色。

    • 对特定对象的追踪
    • 保存用户网页浏览记录与习惯
    • 简化登录

    安全风险:容易泄露用户信息

    典型应用一:判定注册用户是否已经登录网站

    典型应用二:“购物车”的处理

    原理:

    客户端请求服务器时,如果服务器需要记录该用户的状态,就使用response对象向客户端发送一个cookie,客户端浏览器会把cookie保存起来。当浏览器再请求服务器时,浏览器把请求的网址连同该cookie一同提交给服务器,服务器通过检查该cookie来获取用户状态

    Jsp中创建与使用Cookie

    创建Cookie对象

    Cookie newCookie = new Cookie(String key, Object value);
    
    
    // 例如
    Cookie c = new Cookie("username", "peter");
    c.setMaxAge(24*60*60);  // 设置过期时间为1天,单位是秒
    response.addCookie(c);     // 保存 cookie到客户端

    写入Cookie对象

    response.addCookie(newCookie);

    读取Cookie对象

    // 使用 Jsp 读取cookie,需要通过调用 HttpServletRequest 的 getCookies() 方法来创建一个 javax.servlet.http.Cookie 对象的数组。然后循环遍历数组,并使用 getName() 和 getValue() 方法来访问每个cookie和关联的值
    
    
    Cookie[] cookies = request.getCookies();

    常用方法

    void setMaxAge(int expiry)       ---> 设置 cookie 的有效期,以秒为单位

    void setValue(String value)       ---> 在 cookie 创建后,对 cookie 进行赋值

    String getName()                      ---> 获取 cookie 的名称

    String getValue()                       ---> 获取 cookie 的值

    int getMaxAge()                        ---> 获取 cookie 的有效时间,以秒为单位

    示例:新建一个 form.jsp 提交到 setCookies.jsp 页面,在该页面中保存 cookie,然后在 getCookies.jsp 页面读取 cookie

    form.jsp

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h1>用户登录表单</h1>
    <hr>
    
    <form action="setCookies.jsp" method="post">
    用户名:<input type="text" name="username" value=""/>
    密码:<input type="password" name="password" value=""/>
    <input type="submit" value="提交"/>
    
    </form>
    </body>
    </html>

    setCookies.jsp   (这里对保存进cookie中的内容进行编码,否则,读取中文cookie会报错)

    <%@ page language="java" import="java.net.*" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    <h1>接收表单并设置cookies</h1>
    <hr>
    <%
        request.setCharacterEncoding("utf-8");
        // 从request请求中获取用户名和密码
        String username = URLEncoder.encode(request.getParameter("username"), "utf-8");
        String password = URLEncoder.encode(request.getParameter("password"), "utf-8");
        
        // 创建cookie对象
        Cookie usernameCookie = new Cookie("username", username);
        Cookie passwordCookie = new Cookie("password", password);
        
        // 设置Cookie保存时间
        usernameCookie.setMaxAge(24*60*60);
        passwordCookie.setMaxAge(24*60*60);
        
        
        // 保存cookie
        response.addCookie(usernameCookie);
        response.addCookie(passwordCookie);
    %>
    
    
    <a href="getCookies.jsp">查看Cookie</a>
    
    
    </body>
    </html>

    getCookies.jsp (要对cookie进行解码操作)

    <%@ page language="java" import="java.net.*" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    <h1>获取cookies</h1>
    <hr>
    <%
        String username = "";
        String password = "";
        
        // 读取 cookies
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0){
            for(Cookie c:cookies){
                if("username".equals(c.getName())){
                    username = URLDecoder.decode(c.getValue(), "utf-8");
                }
                if("password".equals(c.getName())){
                    password = URLDecoder.decode(c.getValue(), "utf-8");
                }
            }
        }
    %>
    
    
    用户名:<b><%=username %></b><br><br>
    密码:<b><%=password %></b><br><br>
    
    
    </body>
    </html>

    运行效果:

    Session 与 Cookie 对比

    session cookie
    服务器 端保存用户信息 客户端 保存用户信息
    session 中保存的是 Object 类型 cookie 中保存的是 String 类型
    随会话的结束而将其存储的数据 销毁 cookie 可以 长期 保存在客户端
    保存 重要 信息 保存 不重要 的用户信息
  • 相关阅读:
    面试问烂的 MySQL 四种隔离级别,看完吊打面试官!
    一周 GitHub 开源项目推荐:阿里、腾讯、陌陌、bilibili……
    干货收藏 | Java 程序员必备的一些流程图
    IntelliJ IDEA 快捷键终极大全,速度收藏!
    我的天!史上最烂的项目:苦撑 12 年,600 多万行代码...
    模板中如何添加不定个数的常数
    SFINAE简单实例
    Sequentially-consistent ordering
    hierarchical_mutex函数问题(C++ Concurrent in Action)
    不同AI学科之间的联系
  • 原文地址:https://www.cnblogs.com/rogerwu/p/8527977.html
Copyright © 2011-2022 走看看